#####################################################################
## 
##	JSB WAS Auto Setting jython script
##
##                          ThomasDai
##				2017/02/27
##
#####################################################################


import sys
import re
import sre
import time


#############################################
#    Set the Configration Paramaters        #
#############################################
#############################################
#                  Server                   #
#############################################
#name="server1"
#clusterName=""

#Trace#
Trace_enable="true"
Trace_startupTraceSpecification="*=info"
Trace_fileName="${SERVER_LOG_ROOT}/trace.log"
Trace_rolloverSize="20"
Trace_maxNumberOfBackupFiles="10"

#HTTPAccess#
HTTPAccess_enable="true"
HTTPAccess_enableErrorLogging="true"
HTTPAccess_enableAccessLogging="true"

errorLog_filePath="${SERVER_LOG_ROOT}/http_error.log"
errorLog_maximumSize="10"
errorLog_maximumBackupFiles="20"

accessLog_filePath="${SERVER_LOG_ROOT}/http_access.log"
accessLog_maximumSize="10"
accessLog_maximumBackupFiles="20"


#ThreadPool#
ORB_thread_pool_minimumSize="10"
ORB_thread_pool_maximumSize="50"
ORB_thread_pool_inactivityTimeout="3500"
ORB_thread_pool_isGrowable="false"

server_startup_minimumSize="1"
server_startup_maximumSize="3"
server_startup_inactivityTimeout="30000"
server_startup_isGrowable="false"

Default_minimumSize="5"
Default_maximumSize="20"
Default_inactivityTimeout=""
Default_isGrowable=""

WebContainer_minimumSize="150"
WebContainer_maximumSize="150"
WebContainer_inactivityTimeout="3500"
WebContainer_isGrowable="false"

TCPChannel_DCS_minimumSize="20"
TCPChannel_DCS_maximumSize="20"
TCPChannel_DCS_inactivityTimeout=""
TCPChannel_DCS_isGrowable="false"

SIBFAPInboundThreadPool_minimumSize="4"
SIBFAPInboundThreadPool_maximumSize="50"
SIBFAPInboundThreadPool_inactivityTimeout=""
SIBFAPInboundThreadPool_isGrowable=""

SIBFAPThreadPool_minimumSize="4"
SIBFAPThreadPool_maximumSize="50"
SIBFAPThreadPool_inactivityTimeout=""
SIBFAPThreadPool_isGrowable=""

SIBJMSRAThreadPool_minimumSize="35"
SIBJMSRAThreadPool_maximumSize="41"
SIBJMSRAThreadPool_inactivityTimeout="3500"
SIBJMSRAThreadPool_isGrowable=""

WMQJCAResourceAdapter_minimumSize="10"
WMQJCAResourceAdapter_maximumSize="50"
WMQJCAResourceAdapter_inactivityTimeout=""
WMQJCAResourceAdapter_isGrowable=""


#ErrorLog#
ErrorLog_fileName="${SERVER_LOG_ROOT}/SystemErr.log"
ErrorLog_rolloverType="TIME"
ErrorLog_maxNumberOfBackupFiles="10"
ErrorLog_rolloverSize="10"
ErrorLog_baseHour="24"
ErrorLog_rolloverPeriod="24"

#SysLog#
SysLog_fileName="${SERVER_LOG_ROOT}/SystemOut.log"
SysLog_rolloverType="TIME"
SysLog_maxNumberOfBackupFiles="20"
SysLog_rolloverSize="5"
SysLog_baseHour="24"
SysLog_rolloverPeriod="24"

#Transaction#
Transaction_enable="true"
Transaction_totalTranLifetimeTimeout="121"
Transaction_clientInactivityTimeout="61"
Transaction_propogatedOrBMTTranLifetimeTimeout="301"

#Session#
Session_enable="true"
Session_enableUrlRewriting="false"
Session_enableCookies="true"
Session_enableSSLTracking="false"
Session_enableProtocolSwitchRewriting="false"
Session_sessionPersistenceMode="NONE"
Session_allowSerializedSessionAccess="false"
Session_maxWaitTime="5"
Session_accessSessionOnTimeout="true"
Session_maxInMemorySessionCount="1000"
Session_allowOverflow="true"
Session_invalidationTimeout="30"

#webcontainer custom properties#
webcontainerProperties0_name="com.ibm.ws.webcontainer.channelwritetype"
webcontainerProperties0_value="sync"
webcontainerProperties0_required="false"
webcontainerProperties0=[webcontainerProperties0_name,webcontainerProperties0_value,webcontainerProperties0_required]

webcontainerProperties1_name="com.ibm.ws.webcontainer.channelwritetype"
webcontainerProperties1_value="sync"
webcontainerProperties1_required="false"
webcontainerProperties1=[webcontainerProperties1_name,webcontainerProperties1_value,webcontainerProperties1_required]

webcontainerProperties=[webcontainerProperties0,webcontainerProperties1]


#Cookie#
Cookie_maximumAge="-1"
Cookie_secure="false"

#processDefinitions#
stdoutFilename="${SERVER_LOG_ROOT}/native_stdout.log"
stderrFilename="${SERVER_LOG_ROOT}/native_stderr.log"

#environment#
environment0_name="IBM_HEAPDUMP"
environment0_value="true"
environment0_required="false"
environment0=[environment0_name,environment0_value,environment0_required]

environment1_name="IBM_HEAPDUMPDIR"
environment1_value="/var/waslog/WASHeapDump"
environment1_required="false"
environment1=[environment1_name,environment1_value,environment1_required]

environment2_name="IBM_HEAPDUMP_OUTOFMEMORY"
environment2_value="true"
environment2_required="false"
environment2=[environment2_name,environment2_value,environment2_required]

environment3_name="IBM_JAVADUMP_OUTOFMEMORY"
environment3_value="true"
environment3_required="false"
environment3=[environment3_name,environment3_value,environment3_required]

environment4_name="IBM_JAVA_HEAPDUMP_TXT"
environment4_value="true"
environment4_required="false"
environment4=[environment4_name,environment4_value,environment4_required]

environment5_name="IBM_JAVACOREDIR"
environment5_value="/var/waslog/WASHeapDump"
environment5_required="false"
environment5=[environment5_name,environment5_value,environment5_required]

environment6_name="AIXTHREAD_MUTEX_DEBUG"
environment6_value="OFF"
environment6_required="false"
environment6=[environment6_name,environment6_value,environment6_required]

environment7_name="AIXTHREAD_ENRUSG"
environment7_value="ON"
environment7_required="false"
environment7=[environment7_name,environment7_value,environment7_required]

environment8_name="AIXTHREAD_SCOPE"
environment8_value="S"
environment8_required="false"
environment8=[environment8_name,environment8_value,environment8_required]

environment9_name="AIXTHREAD_RWLOCK_DEBUG"
environment9_value="OFF"
environment9_required="false"
environment9=[environment9_name,environment9_value,environment9_required]

environment10_name="AIXTHREAD_COND_DEBUG"
environment10_value="OFF"
environment10_required="false"
environment10=[environment10_name,environment10_value,environment10_required]

environment11_name="_JVM_THREAD_DUMP_BUFFER_SIZE"
environment11_value="25000000"
environment11_required="false"
environment11=[environment11_name,environment11_value,environment11_required]

environment=[environment0,environment1,environment2,environment3,environment4,environment5,environment6,environment7,environment8,environment9,environment10,environment11]

#monitoringPolicy#
monitoringPolicy_maximumStartupAttempts="3"
monitoringPolicy_pingInterval="61"
monitoringPolicy_pingTimeout="301"
monitoringPolicy_autoRestart="true"
monitoringPolicy_nodeRestartState="STOPPED"

#jvmEntries#
jvmEntries_verboseModeClass="false"
jvmEntries_verboseModeGarbageCollection="true"
jvmEntries_verboseModeJNI="false"
jvmEntries_runHProf="false"
jvmEntries_hprofArguments=""
jvmEntries_debugMode="false"
jvmEntries_genericJvmArguments="-Xquickstart -Dlog.id=server1/log1_ -Xgcpolicy:gencon"
jvmEntries_initialHeapSize="128"
jvmEntries_maximumHeapSize="1024"
jvmEntries_disableJIT=""

#jvm systemProperties#
systemProperties0_name="com.ibm.security.jgss.debug"
systemProperties0_value="off"
systemProperties0_required="false"
systemProperties0=[systemProperties0_name,systemProperties0_value,systemProperties0_required]

systemProperties1_name="com.ibm.security.krb5.Krb5Debug"
systemProperties1_value="off"
systemProperties1_required="false"
systemProperties1=[systemProperties1_name,systemProperties1_value,systemProperties1_required]

systemProperties2_name="com.ibm.ws.management.event.pull_notification_timeout"
systemProperties2_value="120000"
systemProperties2_required="false"
systemProperties2=[systemProperties2_name,systemProperties2_value,systemProperties2_required]

systemProperties=[systemProperties0,systemProperties1,systemProperties2]

#admin customProperties#
adminCustomProperties0_name="com.ibm.websphere.threadmonitor.threshold"
adminCustomProperties0_value="300"
adminCustomProperties0_required="false"
adminCustomProperties0=[adminCustomProperties0_name,adminCustomProperties0_value,adminCustomProperties0_required]

adminCustomProperties1_name="com.ibm.websphere.threadmonitor.dump.java"
adminCustomProperties1_value="true"
adminCustomProperties1_required="false"
adminCustomProperties1=[adminCustomProperties1_name,adminCustomProperties1_value,adminCustomProperties1_required]


adminCustomProperties=[adminCustomProperties0,adminCustomProperties1]

#############################################
#           Customer function               #
#############################################

def regexp(pattern, string, flags=0):
    if(re.compile(pattern, flags).search(string)==None): return 0
    else: return 1

def regexpn(pattern, string, flags=0):
    r = re.compile(pattern, flags).subn("", string)
    return r[1]

def wsadminToList(inStr):
    outList=[]
    if (len(inStr)>0 and inStr[0]=='[' and inStr[-1]==']'):
         tmpList = inStr[1:-1].split() #splits space-separated lists,
    else:
         tmpList = inStr.split("\n")   #splits for Windows or Linux
    for item in tmpList:
         item = item.rstrip();         #removes any Windows "\r"
         if (len(item)>0):
             outList.append(item)
    return outList
#endDef

def _splitlines(s):
  rv = [s]
  if '\r' in s:
    rv = s.split('\r\n')
  elif '\n' in s:
    rv = s.split('\n')
  if rv[-1] == '':
    rv = rv[:-1]
  return rv

def getObjectAttribute(objectid, attributename):
    result = AdminConfig.showAttribute(objectid, attributename)
    if result != None and result.startswith("[") and result.endswith("]"):
        result = _splitlist(result)
    return result
      
def getCellName():
    cellObjects = getObjectsOfType('Cell')  # should only be one
    cellname = getObjectAttribute(cellObjects[0], 'name')
    return cellname

def getObjectsOfType(typename, scope = None):
    if scope:
        return _splitlines(AdminConfig.list(typename, scope))
    else:
        return _splitlines(AdminConfig.list(typename))

def getNodeName(node_id):
    return getObjectAttribute(node_id, 'name')
            
def listServersOfTypeSecp(typename):
    result = []
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    cellname = getCellName()
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
        for serverEntry in serverEntries:
            sName = AdminConfig.showAttribute( serverEntry, "serverName" )
            sType = AdminConfig.showAttribute( serverEntry, "serverType" )
            if typename == None or sType == typename:
                result.append(sName)
    return result



def getObjectNameList( typename ):
    """Returns list of names of objects of the given type"""
    m = "getObjectNameList:"
    #sop(m,"Entry. typename=%s" % ( repr(typename) ))
    ids = _splitlines(AdminConfig.list( typename ))
    result = []
    for id in ids:
        result.append(AdminConfig.showAttribute(id,"name"))
    #sop(m,"Exit. result=%s" % ( repr(result) ))
    return result
      
def listVirtualHost():
    """Returns list of names of all ProxySettings objects"""
    return getObjectNameList( 'VirtualHost' )
    
def checkVirtualHost( virtualHost ):
	virtualHostlist = listVirtualHost()
    	for virtualHostOne in virtualHostlist:
    		if virtualHostOne == virtualHost:
    			return	1
	return 0

def getObjectsOfType(typename, scope = None):
    """Return a python list of objectids of all objects of the given type in the given scope
    (another object ID, e.g. a node's object id to limit the response to objects in that node)
    Leaving scope default to None gets everything in the Cell with that type.
    ALWAYS RETURNS A LIST EVEN IF ONLY ONE OBJECT.
    """
    m = "getObjectsOfType:"
    if scope:
        #sop(m, "AdminConfig.list(%s, %s)" % ( repr(typename), repr(scope) ) )
        return _splitlines(AdminConfig.list(typename, scope))
    else:
        #sop(m, "AdminConfig.list(%s)" % ( repr(typename) ) )
        return _splitlines(AdminConfig.list(typename))

def getObjectAttribute(objectid, attributename):
    """Return the value of the named attribute of the config object with the given ID.
    If there's no such attribute, returns None.
    If the attribute value looks like a list, converts it to a real python list.
    TODO: handle nested "lists"
    """
    #sop("getObjectAttribute:","AdminConfig.showAttribute(%s, %s)" % ( repr(objectid), repr(attributename) ))
    result = AdminConfig.showAttribute(objectid, attributename)
    if result != None and result.startswith("[") and result.endswith("]"):
        # List looks like "[value1 value2 value3]"
        result = _splitlist(result)
    return result
    
def getCellName():
    """Return the name of the cell we're connected to"""
    # AdminControl.getCell() is simpler, but only
    # available if we're connected to a running server.
    cellObjects = getObjectsOfType('Cell')  # should only be one
    cellname = getObjectAttribute(cellObjects[0], 'name')
    return cellname

def getNodeId( nodename ):
    """Given a node name, get its config ID"""
    return AdminConfig.getid( '/Cell:%s/Node:%s/' % (getCellName(), nodename ))
    
def nodeIsDmgr( nodename ):
    """Return true if the node is the deployment manager"""
    return nodeHasServerOfType( nodename, 'DEPLOYMENT_MANAGER' )

def nodeHasServerOfType( nodename, servertype ):
    node_id = getNodeId(nodename)
    serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
    for serverEntry in serverEntries:
        sType = AdminConfig.showAttribute( serverEntry, "serverType" )
        if sType == servertype:
            return 1
    return 0

def getNodeName(node_id):
    """Get the name of the node with the given config object ID"""
    return getObjectAttribute(node_id, 'name')

      
def listNodes():
    """Return list of node names, excluding the dmgr node.
       Beware, this list will include any existing IHS nodes."""
    m = "listNodes:"
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    result = []
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        if not nodeIsDmgr(nodename):
            result.append(nodename)
    if 0 == len(result):
        sop(m,"Warning. No non-manager nodes are defined!!!")
    return result

def listUnclusteredServers():
    """Return a list of app servers that don't belong to clusters, as a list of lists
    (see listServersOfType)"""
    allServers = listServersOfType('APPLICATION_SERVER')
    result = []
    for (nodename,servername) in allServers:
        server_id = getServerByNodeAndName(nodename,servername)
        clusterName = AdminConfig.showAttribute(server_id, 'clusterName')
        if clusterName == None:
            result.append([nodename,servername])
    return result

def getServerByNodeAndName( nodename, servername ):
    """Return config id for a server"""
    return getObjectByNodeAndName( nodename, 'Server', servername )

def getObjectByNodeAndName( nodename, typename, objectname ):
    """Get the config object ID of an object based on its node, type, and name"""
    # This version of getObjectByName distinguishes by node,
    # which should disambiguate some things...
    node_id = getNodeId(nodename)
    all = _splitlines(AdminConfig.list( typename, node_id ))
    result = None
    for obj in all:
        name = AdminConfig.showAttribute( obj, 'name' )
        if name == objectname:
            if result != None:
                raise "FOUND more than one %s with name %s" % ( typename, objectname )
            result = obj
    return result
               
def nodeIsUnmanaged( nodename ):
    """Return true if the node is an unmanaged node."""
    return not nodeHasServerOfType( nodename, 'NODE_AGENT' )
    
def syncall():
    m = "wsadminlib.syncall"
    """Sync config to all nodes - return 0 on success, non-zero on error"""
    print "Sync all node start..."
    returncode = 0

    nodenames = listNodes()
    for nodename in nodenames:
        # Note: listNodes() doesn't include the dmgr node - if it did, we'd
        # have to skip itn
        # We do, however, have to skip unmanaged nodes.  These will show up
        # when there is a web server defined on a remote machine.
        if not nodeIsDmgr( nodename ) and not nodeIsUnmanaged( nodename ):
            sop(m,"Sync config to node %s" % nodename)
            Sync1 = AdminControl.completeObjectName( "type=NodeSync,node=%s,*" % nodename )
            if Sync1:
                rc = AdminControl.invoke( Sync1, 'sync' )
                if rc != 'true':  # failed
                    sop(m,"Sync of node %s FAILED" % nodename)
                    returncode = 1
            else:
                sop(m,"WARNING: was unable to get sync object for node %s - is node agent running?" % nodename)
                returncode = 2
    if returncode != 0:
        sop(m,"Syncall FAILED")
    sop(m,"Done")
    return returncode
    
DEBUG_SOP=1

def sop(methodname,message):
    """Prints the specified method name and message with a nicely formatted timestamp.
    (sop is an acronym for System.out.println() in java)"""
    global DEBUG_SOP
    if(DEBUG_SOP):
        timestamp = getSopTimestamp()
        print "%s %s %s" % (timestamp, methodname, message)

def getSopTimestamp():
    """Returns the current system timestamp in a nice internationally-generic format."""
    # Assemble the formatting string in pieces, so that some code libraries do not interpret
    # the strings as special keywords and substitute them upon extraction.
    formatting_string = "[" + "%" + "Y-" + "%" + "m" + "%" + "d-" + "%" + "H" + "%" + "M-" + "%" + "S00]"
    return time.strftime(formatting_string)

def isServerRunning(nodename,servername):
    """Returns a boolean to say if the server is running.
Not 100% accurate but should be close - relies on there only being an mbean for
    a server if it's running"""
    mbean = AdminControl.queryNames('type=Server,node=%s,name=%s,*' % (nodename,servername))
    if mbean:
        return 1
    else :
    	return 0

waitForServerStartSecs = 300
    
def startServer( nodename, servername ):
    """Start the named server - raises exception on error.
    Uses global variable waitForServerStartSeconds"""
    # Check first if it's already running - if we try to start it
    # when it's running, we get an exception and sometimes the
    # try/except below doesn't catch it, I don't know why
    m = "startServer:"
    if isServerRunning(nodename,servername):
        sop(m,"server %s,%s is already running" % (nodename,servername))
    else:
        sop(m,"starting server %s,%s" % (nodename,servername))
        try:
            sop(m,"startServer(%s,%s)" % ( servername, nodename ))
            # optional the 3rd arg is seconds to wait for startup - the default
            # is 1200 (according to 6.1 infocenter) e.g. 20 minutes,
            # which you'd think would be enough for anybody...
            # But it actually doesn't seem to work that way, so put an explicit
            # and long wait time.
            # But if we put 3600, we get a SOAP timeout... going back
            # to 120 for now
            AdminControl.startServer( servername, nodename, 240)

            # Calculate the number of 15-second cycles to wait, minimum 1.
            global waitForServerStartSecs
            waitRetries = waitForServerStartSecs / 15
            if waitRetries < 1:
                waitRetries = 1
            retries = 0
            while not isServerRunning(nodename,servername) and retries < waitRetries:
                sop(m,"server %s,%s not running yet, waiting another 15 secs" % (nodename,servername))
                time.sleep(15)  # seconds
                retries += 1
            if not  isServerRunning(nodename,servername) :
                sop(m,"server %s,%s STILL not running, giving up" % (nodename,servername))
                raise Exception("SERVER FAILED TO START %s,%s" % (nodename,servername))
            else :
            	sop(m,"server %s,%s are running, good luck" % (nodename,servername))

        except:
            # Fails if server already started - ignore it
            ( exception, parms, tback ) = sys.exc_info()
            if -1 != repr( parms ).find( "already running" ):
                return                      # ignore it
            # Some other error? scream and shout
            sop(m,"EXCEPTION STARTING SERVER %s" % servername)
            sop(m,"Exception=%s\nPARMS=%s" % ( str( exception ), repr( parms ) ))
            raise Exception("EXCEPTION STARTING SERVER %s: %s %s" % (servername, str(exception),str(parms)))

def startCluster( clustername ):
    """Start the named server cluster"""
    m = "startCluster:"
    sop(m,"Start cluster %s" % clustername)
    cellname = getCellName()    # e.g. 'poir1Cell01'
    cluster = AdminControl.completeObjectName( 'cell=%s,type=Cluster,name=%s,*' % ( cellname, clustername ) )
    state = AdminControl.getAttribute( cluster, 'state' )
    if state != 'websphere.cluster.partial.start' and state != 'websphere.cluster.running':
        AdminControl.invoke( cluster, 'start' )
    # Wait for it to start
    maxwait = 300  # wait about 5 minutes at most
    count = 0
    sop(m,"wait for cluster %s to start" % clustername)
    while state != 'websphere.cluster.running':
        time.sleep( 30 )
        state = AdminControl.getAttribute( cluster, 'state' )
        sop(m,"state of %s: %s" % ( clustername, state ))
        count += 1
        if count > ( maxwait / 30 ):
            sop(m,"Giving up")
            break
            
def startApplication(appname):
    """Start the named application on all its servers.

    Note: This method assumes the application is installed on all servers.
    To start an application on an individual server, use startApplicationOnServer()
    To start an application on all members of a cluster, use startApplicationOnCluster()"""
    m = "startApplication:"
    sop(m,"Entry. appname=%s" % ( appname ))
    cellname = getCellName()
    servers = listServersOfType('APPLICATION_SERVER')
    for (nodename,servername) in servers:
        sop(m,"Handling cellname=%s nodename=%s servername=%s" % ( cellname, nodename, servername ))
        # Get the application manager MBean
        appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
        # start it
        sop(m,"Starting appname=%s" % ( appname ))
        AdminControl.invoke(appManager, 'startApplication', appname)
        # FIXME: not working on Base unmanaged server on z/OS for some reason
        # Not sure if it works anywhere since usually I just start the
        # servers after configuration and don't need to explicitly start
        # the applications
    sop(m,"Exit.")

def isApplicationRunning(appname):
    """Returns a boolean which indicates whether the application is running.
    see http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.nd.doc/info/ae/ae/txml_adminappobj.html """
    mbean = AdminControl.queryNames('type=Application,name=%s,*' % ( appname ))
    if mbean:
        return 1
    return 0
    
def startApplicationOnServer(appname,nodename,servername):
    """Start the named application on one servers"""
    m = "startApplicationOnServer:"
    sop(m,"Entry. appname=%s nodename=%s servername=%s" % ( appname,nodename,servername ))
    cellname = getCellName()
    # Get the application manager MBean
    appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
    sop(m,"appManager=%s" % ( repr(appManager) ))
    # start it
    rc = AdminControl.invoke(appManager, 'startApplication', appname)
    sop(m,"Exit. rc=%s" % ( repr(rc) ))
    
def stopApplicationOnServer(appname,nodename,servername):
    """Stop the named application on one servers"""
    m = "stopApplicationOnServer:"
    sop(m,"Entry. appname=%s nodename=%s servername=%s" % ( appname,nodename,servername ))
    cellname = getCellName()
    # Get the application manager MBean
    appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
    sop(m,"appManager=%s" % ( repr(appManager) ))
    # start it
    rc = AdminControl.invoke(appManager, 'stopApplication', appname)
    sop(m,"Exit. rc=%s" % ( repr(rc) ))   

def listServersInCluster(clusterName):
    """Return a list of all servers (members) that are in the specified cluster"""
    m = "listServersInCluster:"
    sop(m,"clusterName = %s" % clusterName)
    clusterId = AdminConfig.getid("/ServerCluster:" + clusterName + "/")
    clusterMembers = _splitlines(AdminConfig.list("ClusterMember", clusterId ))
    return clusterMembers
    
def startApplicationOnCluster(appname,clustername):
    """Start the named application on all servers in named cluster"""
    m = "startApplicationOnCluster:"
    sop(m,"Entry. appname=%s clustername=%s" % ( appname, clustername ))
    server_id_list = listServersInCluster( clustername )
    for server_id in server_id_list:
        nodename = AdminConfig.showAttribute( server_id, "nodeName" )
        servername = AdminConfig.showAttribute( server_id, "memberName" )
        sop(m, "Starting application. application=%s cluster=%s node=%s server=%s" % (appname, clustername, nodename, servername) )
        startApplicationOnServer(appname,nodename,servername)
    sop(m,"Exit.")
    
def stopApplicationOnCluster(appname,clustername):
    """Stop the named application on all servers in named cluster"""
    m = "stopApplicationOnCluster:"
    sop(m,"Entry. appname=%s clustername=%s" % ( appname, clustername ))
    server_id_list = listServersInCluster( clustername )
    for server_id in server_id_list:
        nodename = AdminConfig.showAttribute( server_id, "nodeName" )
        servername = AdminConfig.showAttribute( server_id, "memberName" )
        sop(m, "Starting application. application=%s cluster=%s node=%s server=%s" % (appname, clustername, nodename, servername) )
        stopApplicationOnServer(appname,nodename,servername)
    sop(m,"Exit.")
################################################################
# Declare Java classes for getting property pairs from props file
#################################################################
def loadProperties ( propFileName ):
        print "loading prop file "+propFileName
        from java.io import FileInputStream
        from java.util import Properties

        fileprop = Properties(  ) #?PROBLEM? (jacl 10) JAVA::NEW Properties might require:  from ?? import Properties
        fileStream = FileInputStream( propFileName ) #?PROBLEM? (jacl 11) JAVA::NEW FileInputStream might require:  from ?? import FileInputStream

        _J2J_file_ = open(fileStream)
        _J2J_lines_ = _J2J_file_.readlines()
        fileprop = {} 
        for _J2J_line_ in _J2J_lines_:
                _J2J_line_ = _J2J_line_.strip()
                if(len(_J2J_line_)==0 or _J2J_line_[0:1]=="#"): continue
                _J2J_index_ = _J2J_line_.find("=")
                fileprop[_J2J_line_[0:_J2J_index_]] = _J2J_line_[_J2J_index_+1:]
        #endFor (read of propertyFile=fileStream into variable=fileprop)
        _J2J_file_.close()

        return fileprop
#endDef 

def installApplication( filename, servers, clusternames, options ):
    """Install application and map to the named servers/clusters
    with the given options.

    "servers" is a list of dictionaries, each specifying a 'nodename'
    and 'servername' for one server to map the app to.

    "clusternames" is a list of cluster names to map the app to.


    options can be None, or else a list of additional options to pass.
    E.g. ['-contextroot', '/b2bua']
    See the doc for AdminApp.install for full details.
    """
    m = "installApplication:"

    sop(m,"filename=%s, servers=%s, clusternames=%s, options=%s" % (filename,repr(servers),repr(clusternames),options))
    targets = []
    cellname = getCellName()
    if servers != None:
    	for server in servers:
        	targets.append("WebSphere:cell=%s,node=%s,server=%s" % (cellname, server['nodename'], server['servername']))
    if clusternames != None:
    	for clustername in clusternames:
        	targets.append("WebSphere:cell=%s,cluster=%s" % (cellname,clustername))

    target = "+".join( targets )
    print target

    arglist = ['-target', target, ]

    # Set a default virtual host mapping if the caller does not specify one.
    if options != None:
        if not "-MapWebModToVH" in options:
        	virhosttmp = checkVirtualHost(virtual_host)
        	print virhosttmp
        	if virhosttmp == 1:
            		arglist.extend( ['-MapWebModToVH', [['.*', '.*', virtual_host ]]] )
            	else:
			print "virtual_host: This virtual_host can not be found in current Dmgr env..."
			sys.exit()

    # Append caller-specified options.
    if options != None:
        arglist.extend(options)
    sop(m,"Calling AdminApp.install of %s with arglist = %s" % ( filename, repr(arglist) ))
    AdminApp.install( filename, arglist )
#endDef 

def getAdminAppViewValue(appname, keyname, parsename):
    """This helper method returns the value for the specified application
    and key name, as fetched by AdminApp.view().

    Parms: appname - the name of the application
           keyname - the name of the app parameter, eg CtxRootForWebMod
           parsename - the string used to parse results, eg Context Root:
    For example, getAdminApp.view('wussmaster',"-CtxRootForWebMod","Context Root:")

    This method is useful because AdminApp.view() returns a verbose
    multi-line string intended for human viewing and consumption, for example:
        CtxRootForWebMod: Specify the Context root of web module

        Configure values for context roots in web modules.

        Web module:  wussmaster
        URI:  wussmaster.war,WEB-INF/web.xml
        Context Root:  wussmaster
    This method returns a short string useful programmatically.

    Returns None if trouble is encountered."""
    m = "getAdminAppViewValue:"
    sop(m,"Entry. appname=%s keyname=%s parsename=%s" % ( appname, keyname, parsename ))

    # Fetch a verbose human-readable string from AdminApp.view()
    verboseString = AdminApp.view(appname, [keyname])
    sop(m,"verboseString=%s" % ( verboseString ))
    verboseStringList = _splitlines(verboseString)
    for str in verboseStringList:
        #sop("","str=>>>%s<<<" % ( str ))
        if str.startswith(parsename):
            resultString = str[len(parsename):].strip()
            sop(m,"Exit. Found value. Returning >>>%s<<<" % ( resultString ))
            return resultString

    sop(m,"Exit. Did not find value. Returning None.")
    return None

def getApplicationContextRoot(appname):
    """Returns the context root value for the specified application.
    Returns None if trouble is encountered."""
    return getAdminAppViewValue(appname, "-CtxRootForWebMod", "Context Root:")
    
def getDmgrNode():
    """Return config id of the Dmgr node"""
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        if nodeIsDmgr(nodename):
            return node_id
    return None
    
def getDmgrNodeName():
    """Return node name of the Dmgr node"""
    return getNodeName(getDmgrNode())

base_nd_flag = ""
def isND():
    """Are we connected to a ND system"""
    global base_nd_flag
    if base_nd_flag == "":
        _whatEnv()
    return base_nd_flag == 'nd'

def _whatEnv():
    """Not user callable
    Sets some flags that other things use"""
    m = "_whatEnv:"


    global base_nd_flag
    base_nd_flag = whatEnv()

def whatEnv():
    """Returns 'nd' if connected to a dmgr, 'base' if connected to
    an unmanaged server, and 'other' if connected to something else
    (which shouldn't happen but could)"""
    m = "whatEnv:"

    # Simpler version - should work whether connected or not
    servers = getObjectsOfType('Server')
    for server in servers:
        servertype = getObjectAttribute(server, 'serverType')
        if servertype == 'DEPLOYMENT_MANAGER':
            return 'nd'  # we have a deployment manager
    return 'base'  # no deployment manager, must be base

def compareIntLists(a, b):
    """Compares two python lists containing ints.

       Returns -1 if array a sorts before array b.
       Returns 0 if they're the same.
       Returns +1 if array a sorts after array b.

       This method was ported from FritzUtils.java"""
    m = "compareIntArrays:"
    # sop(m,"Entry. a=%s b=%s" % ( a, b, ))

    i = 0
    while (i<len(a) and i<len(b)):
        if (a[i] < b[i]):
            # sop(m,"Exit 1. a[i]<b[i]. i=%i a[i]=%i b[i]=%i" % ( i, a[i], b[i] ))
            return -1
        if (a[i] > b[i]):
            # sop(m,"Exit 2. a[i]>b[i]. i=%i a[i]=%i b[i]=%i" % ( i, a[i], b[i] ))
            return 1
        # No decision yet.
        i = i + 1
    # So far, still the same... is one longer? it goes later.
    if (len(a) < len(b)):
        # sop(m,"Exit 3. len(a)<len(b). len(a)=%i len(b)=%i" % ( len(a), len(b) ))
        return -1
    if (len(a) > len(b)):
        # sop(m,"Exit 4. len(a)>len(b). len(a)=%i len(b)=%i" % ( len(a), len(b) ))
        return -1
    # sop(m,"Exit 5. a=b. Returning zero.")
    return 0;

def parseVersion(stringVersion):
    """Parses a version string like "6.1.0.3" and
       returns a python list of ints like [ 6,1,0,3 ]

       This method was ported from FritzUtils.java"""
    m = "parseVersion:"
    # sop(m,"Entry. stringVersion=%s" % ( stringVersion ))
    listVersion = []
    parts = stringVersion.split('.')
    for part in parts:
        # sop(m,"Adding part=%s" % part)
        listVersion.append(int(part))
    # sop(m,"Exit. Returning listVersion=%s" % ( listVersion ))
    return listVersion
        
def versionAtLeast(nodename, stringVersion):
    """Returns true if the version we're running is greater than or equal to the version passed in.

       For example, pass in '6.1.0.13.
       If we're running 6.1.0.13, or 7.0.0.0, it returns true.
       If we're running 6.1.0.12, it returns false.

       This method was ported from FritzUtils.java"""

    # m = "versionAtLeast:"
    # sop(m,"Entry. nodename=%s stringVersion=%s" % (nodename,stringVersion))
    x = compareIntLists(parseVersion(getNodeVersion(nodename)),parseVersion(stringVersion))
    # sop(m,"Exit. x=%i Returning %s" % ( x, (x>=0) ))
    return (x >= 0)

def getNodeVersion(nodename):
    """Return the WebSphere version of the node - e.g. "6.1.0.0"  - only we're connected
    to a running process.
    If we ever need it to work when server is not running, we can get at least
    minimal information from the node-metadata.properties file in the node's
    config directory."""
    sop("getNodeVersion:", "AdminTask.getNodeBaseProductVersion('[-nodeName %s]')" %  nodename )
    version = AdminTask.getNodeBaseProductVersion(  '[-nodeName %s]' %  nodename   )
    return version

def getNodePlatformOS(nodename):
    """Get the OS of the named node (not sure what format it comes back in).
    Some confirmed values: 'linux', 'windows', 'os390', 'solaris', 'hpux'
    I think these come from node-metadata.properties, com.ibm.websphere.nodeOperatingSystem;
    on that theory, AIX should return 'aix'.
    """
    return AdminTask.getNodePlatformOS('[-nodeName %s]' % nodename)
    
def getNodeNameList(platform=None,servertype=None):
    """Returns a list with node names which match the specified platform and server type.
    Parameter 'platform' may be linux, windows, os390, etc. It defaults to return all platforms.
    Parameter 'servertype' may be APPLICATION_SERVER, PROXY_SERVER, etc. It defaults to all types.
    For example, this returns a list of proxies on hpux:
        hpuxProxyList = getNodeNameList(platform='hpux',servertype='PROXY_SERVER')
    """
    m = "getNodeNameList: "
    #sop(m,"Entry. platform=%s servertype=%s" % ( platform, servertype ))

    nodelist = []
    serverlist = listServersOfType(servertype)
    #sop(m,"serverlist=%s" % ( repr(serverlist) ))
    for (nodename,servername) in serverlist:
        actual_platform = getNodePlatformOS(nodename)
        #sop(m,"nodename=%s servername=%s actual_platform=%s" % ( nodename, servername, actual_platform ))
        if None == platform or actual_platform == platform:
            if nodename not in nodelist:
                nodelist.append(nodename)
                #sop(m,"Saved node")

    #sop(m,"Exit. Returning nodelist=%s" % ( repr(nodelist) ))
    return nodelist

def listServersOfType(typename):
    """return a list of servers of a given type as a list of lists.
    E.g. [['nodename','proxyname'], ['nodename','proxyname']].
    Typical usage:
    for (nodename,servername) in listServersOfType('PROXY_SERVER'):
        callSomething(nodename,servername)
    Set typename=None to return all servers.
        """
    # Go through one node at a time - can't figure out any way to
    # find out what node a server is in from the Server or ServerEntry
    # object
    result = []
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    cellname = getCellName()
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
        for serverEntry in serverEntries:
            sName = AdminConfig.showAttribute( serverEntry, "serverName" )
            sType = AdminConfig.showAttribute( serverEntry, "serverType" )
            if typename == None or sType == typename:
                result.append([nodename, sName])
    return result
        
def listServerClusters():
    """Return list of names of server clusters"""
    cluster_ids = _splitlines(AdminConfig.list( 'ServerCluster' ))
    cellname = getCellName()
    result = []
    for cluster_id in cluster_ids:
        result.append(AdminConfig.showAttribute(cluster_id,"name"))
    return result
                            
def listApplications():
    """Return list of all application names.
    Note: the admin console is included - it's called 'isclite' in v6.1, don't know on other versions"""
    if isND():
        nodename = getDmgrNodeName()
    else:
        nodename = listNodes()[0]  # there will only be one
    if versionAtLeast(nodename, "6.1.0.0"):
        return _splitlines(AdminApp.list( 'WebSphere:cell=%s' % getCellName() ))
    else:
        # for 6.0.2 support
        return _splitlines(AdminApp.list())

def saveAndSync():
    """Save config changes and sync them - return 0 on sync success, non-zero on failure"""
    m = "save:"
    sop(m, "AdminConfig.queryChanges()")
    changes = _splitlines(AdminConfig.queryChanges())
    for change in changes:
        sop(m, "  "+change)
    rc = 0;
    AdminConfig.setSaveMode("overwriteOnConflict")
    sop(m, "AdminConfig.getSaveMode()")
    mode = AdminConfig.getSaveMode()

    sop(m, "  "+mode)
    sop(m, "AdminConfig.save()")
    AdminConfig.save()
    sop(m, "  Save complete!")
    rc = syncall()
    return rc
    
def updateApplication(appname,filename):
    """Update an application with a new ear file"""
    # We need to know the application name - it's in an xml file
    # in the ear
   	#added by lwm 
    if earFileLocationLower.endswith(".zip"):
			AdminApp.update(appname,            # name of application
	                    'partialapp',              # type of update to do  
	                    # options:
	                    ['-contents', filename,
	                     ],
	                    )
    else:
      AdminApp.update(appname,            # name of application
	                     'app',              # type of update to do
	                    # options:
	                    ['-operation', 'update', # redundant but required
	                    '-contents', filename,
	                    ],
	                    )
    
def deleteApplicationByName( name ):
    """Delete the named application from the cell"""
    AdminApp.uninstall( name )

def getServerClusterByName( name ):
    """Return the config object id for the named server cluster
    TODO: get rid of either this or getClusterId"""
    return getObjectByName( 'ServerCluster', name )

def getObjectByName( typename, objectname ):
    """Get an object of a given type and name - WARNING: the object should be unique in the cell; if not, use getObjectByNodeAndName instead."""
    all = _splitlines(AdminConfig.list( typename ))
    result = None
    for obj in all:
        name = AdminConfig.showAttribute( obj, 'name' )
        if name == objectname:
            if result != None:
                raise "FOUND more than one %s with name %s" % ( typename, objectname )
            result = obj
    return result

def deleteApplicationByNameIfExists( applicationName ):
    """Delete the application if it already exists.

    Return true (1) if it existed and was deleted.
    Return false (0) if it did not exist."""
    m = "deleteApplicationByNameIfExists:"
    sop(m,"Application Name = %s" % applicationName)
    apps = listApplications()
    sop(m,repr(apps))
    if applicationName in apps:
        sop(m,"Removing Application: %s" % repr(applicationName))
        deleteApplicationByName(applicationName)
        # Did exist and has been deleted, return true (1)
        return 1
    # Did not exist, did not delete, return false (0)
    return 0

def restartServer( nodename, servername, maxwaitseconds, ):

    m = "restartServer: "
    sop(m,"Entry. nodename=%s servername=%s maxwaitseconds=%d" % (nodename, servername, maxwaitseconds, ))

    if not isServerRunning( nodename, servername ):
        raise m + "ERROR: Server is not already running. nodename=%s servername=%s" % (nodename, servername, )
    sop(m,"Server %s is running." % ( servername, ))

    # Get the server mbean
    serverObjectName = AdminControl.completeObjectName('type=Server,node=%s,process=%s,*' % ( nodename, servername ,))
    sop(m,"Invoking restart on server. serverObjectName=%s" % ( serverObjectName, ))

    # Restart the server.
    AdminControl.invoke(serverObjectName, 'restart')

    # Wait up to a max timeout if requested by the caller.
    elapsedtimeseconds = 0
    if maxwaitseconds > 0:
        sleeptimeseconds = 1

        # Phase 1 - Wait for server to stop (This can take 30 seconds on a reasonably fast linux intel box)
        isRunning = isServerRunning( nodename, servername )
        while isRunning and elapsedtimeseconds < maxwaitseconds:
            sop(m,"Waiting %d of %d seconds for %s to stop. isRunning=%s" % ( elapsedtimeseconds, maxwaitseconds, servername, isRunning, ))
            time.sleep( sleeptimeseconds )
            elapsedtimeseconds = elapsedtimeseconds + sleeptimeseconds
            isRunning = isServerRunning( nodename, servername )

        # Phase 2 - Wait for server to start (This can take another minute)
        while not isRunning and elapsedtimeseconds < maxwaitseconds:
            sop(m,"Waiting %d of %d seconds for %s to restart. isRunning=%s" % ( elapsedtimeseconds, maxwaitseconds, servername, isRunning, ))
            time.sleep( sleeptimeseconds )
            elapsedtimeseconds = elapsedtimeseconds + sleeptimeseconds
            isRunning = isServerRunning( nodename, servername )

    isRunning = isServerRunning( nodename, servername )
    sop(m,"Exit. nodename=%s servername=%s maxwaitseconds=%d elapsedtimeseconds=%d Returning isRunning=%s" % (nodename, servername, maxwaitseconds, elapsedtimeseconds, isRunning ))
    return isRunning
    
def stopCluster( clustername ):
    """Stop the named server cluster"""
    m = "stopCluster:"
    sop(m,"Stop cluster %s" % clustername)
    cellname = getCellName()    # e.g. 'poir1Cell01'
    cluster = AdminControl.completeObjectName( 'cell=%s,type=Cluster,name=%s,*' % ( cellname, clustername ) )
    state = AdminControl.getAttribute( cluster, 'state' )
    if state != 'websphere.cluster.partial.stop' and state != 'websphere.cluster.stopped':
        AdminControl.invoke( cluster, 'stop' )
    # Wait for it to stop
    maxwait = 300  # wait about 5 minutes at most
    count = 0
    sop(m,"wait for cluster %s to stop" % clustername)
    while state != 'websphere.cluster.stopped':
        time.sleep( 30 )
        state = AdminControl.getAttribute( cluster, 'state' )
        sop(m,"state of %s: %s" % ( clustername, state ))
        count += 1
        if count > ( maxwait / 30 ):
            sop(m,"Giving up")
            break
            
def getNodePlatformOS(nodename):
    """Get the OS of the named node (not sure what format it comes back in).
    Some confirmed values: 'linux', 'windows', 'os390', 'solaris', 'hpux'
    I think these come from node-metadata.properties, com.ibm.websphere.nodeOperatingSystem;
    on that theory, AIX should return 'aix'.
    """
    return AdminTask.getNodePlatformOS('[-nodeName %s]' % nodename)

def getNodeHostname(nodename):
    """Get the hostname of the named node"""
    return AdminConfig.showAttribute(getNodeId(nodename),'hostName')
        
def serverStatus():
    """Display the status of all nodes, servers, clusters..."""
    print "Server status"
    print "============="

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        if nodeIsDmgr(nodename):
            print "NODE %s on %s (%s) - Deployment manager" % (nodename,hostname,platform)
        else:
            print "NODE %s on %s (%s)" % (nodename,hostname,platform)
            serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
            for serverEntry in serverEntries:
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                isRunning = isServerRunning(nodename,sName)
                if isRunning: status = "running"
                else: status = "stopped"
                print "\t%-18s %-15s %s" % (sType,sName,status)

    appnames = listApplications()
    print "APPLICATIONS:"
    for a in appnames:
        if a != 'isclite' and a != 'filetransfer':
            print "\t%s" % a
            
def restartNodeagent( nodename, servername):

    m = "restartServer: "
    sop(m,"Entry. nodename=%s servername=%s " % (nodename, servername, ))

    if isServerRunning( nodename, servername ):
#        raise m + "ERROR: Server is not already running. nodename=%s servername=%s" % (nodename, servername, )
#    sop(m,"Server %s is running." % ( servername, ))

    # Get the server mbean
    	serverObjectName = AdminControl.completeObjectName('type=Server,node=%s,process=%s,*' % ( nodename, servername ,))
    	sop(m,"Invoking restart on server. serverObjectName=%s" % ( serverObjectName, ))

    # Restart the server.
    	AdminControl.invoke(serverObjectName, 'restart')

def nodeagentStatus():
    """Display the status of all nodes..."""
    print "Server status"
    print "============="

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        if nodeIsDmgr(nodename):
            print "NODE %s on %s (%s) - Deployment manager" % (nodename,hostname,platform)
        else:
            print "NODE %s on %s (%s)" % (nodename,hostname,platform)
            serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
            for serverEntry in serverEntries:
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                if (sType == "NODE_AGENT"):
                	isRunning = isServerRunning(nodename,sName)
                	if isRunning: status = "running"
                	else: status = "stopped"
                	print "\t%-18s %-15s %s" % (sType,sName,status)

def restartAllNodeagent():
    """restart all nodes..."""

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        
        print "NODE %s on %s (%s)" % (nodename,hostname,platform)
        
        serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
        for serverEntry in serverEntries:
        	
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                if (sType == "NODE_AGENT"):
                	isRunning = isServerRunning(nodename,sName)
                	if isRunning: status = "running"
                	else: status = "stopped"
                	print "\t%-18s %-15s %s" % (sType,sName,status)
                	restartNodeagent(nodename,"nodeagent")
                	

def isGlobalSecurityEnabled():
    """ Check if Global Security is enabled. If security is enabled return True else False"""
    m = "isGlobalSecurityEnabled"
    sop(m,"Entry: Checking if Global Security is enabled...")
    securityon = AdminTask.isGlobalSecurityEnabled()
    sop(m,"Global Security enabled: %s" % (securityon))
    return securityon

def _getSecurityId():
    global AdminControl, AdminConfig
    cellName = getCellName()
    try:
        param = "/Cell:" + cellName + "/Security:/"
        secId = AdminConfig.getid(param)
        if len(secId) == 0:
            print "Security ConfigId was not found"
            return None

        #print "Got Security ConfigId is " + secId
        return secId
    except:
        print "AdminConfig.getid(%s) caught an exception" % param
        return None

def getObjectNameList( typename ):
    """Returns list of names of objects of the given type"""
    m = "getObjectNameList:"
    #sop(m,"Entry. typename=%s" % ( repr(typename) ))
    ids = _splitlines(AdminConfig.list( typename ))
    result = []
    for id in ids:
        result.append(AdminConfig.showAttribute(id,"name"))
    #sop(m,"Exit. result=%s" % ( repr(result) ))
    return result
      
def listVirtualHost():
    """Returns list of names of all ProxySettings objects"""
    return getObjectNameList( 'VirtualHost' )
    
def checkVirtualHost( virtualHost ):
	virtualHostlist = listVirtualHost()
    	for virtualHostOne in virtualHostlist:
    		if virtualHostOne == virtualHost:
    			return	1
	return 0

def getObjectsOfType(typename, scope = None):
    """Return a python list of objectids of all objects of the given type in the given scope
    (another object ID, e.g. a node's object id to limit the response to objects in that node)
    Leaving scope default to None gets everything in the Cell with that type.
    ALWAYS RETURNS A LIST EVEN IF ONLY ONE OBJECT.
    """
    m = "getObjectsOfType:"
    if scope:
        #sop(m, "AdminConfig.list(%s, %s)" % ( repr(typename), repr(scope) ) )
        return _splitlines(AdminConfig.list(typename, scope))
    else:
        #sop(m, "AdminConfig.list(%s)" % ( repr(typename) ) )
        return _splitlines(AdminConfig.list(typename))

def getObjectAttribute(objectid, attributename):
    """Return the value of the named attribute of the config object with the given ID.
    If there's no such attribute, returns None.
    If the attribute value looks like a list, converts it to a real python list.
    TODO: handle nested "lists"
    """
    #sop("getObjectAttribute:","AdminConfig.showAttribute(%s, %s)" % ( repr(objectid), repr(attributename) ))
    result = AdminConfig.showAttribute(objectid, attributename)
    if result != None and result.startswith("[") and result.endswith("]"):
        # List looks like "[value1 value2 value3]"
        result = _splitlist(result)
    return result
    
def getCellName():
    """Return the name of the cell we're connected to"""
    # AdminControl.getCell() is simpler, but only
    # available if we're connected to a running server.
    cellObjects = getObjectsOfType('Cell')  # should only be one
    cellname = getObjectAttribute(cellObjects[0], 'name')
    return cellname

def getNodeId( nodename ):
    """Given a node name, get its config ID"""
    return AdminConfig.getid( '/Cell:%s/Node:%s/' % (getCellName(), nodename ))
    
def nodeIsDmgr( nodename ):
    """Return true if the node is the deployment manager"""
    return nodeHasServerOfType( nodename, 'DEPLOYMENT_MANAGER' )

def nodeHasServerOfType( nodename, servertype ):
    node_id = getNodeId(nodename)
    serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
    for serverEntry in serverEntries:
        sType = AdminConfig.showAttribute( serverEntry, "serverType" )
        if sType == servertype:
            return 1
    return 0

def getNodeName(node_id):
    """Get the name of the node with the given config object ID"""
    return getObjectAttribute(node_id, 'name')

      
def listNodes():
    """Return list of node names, excluding the dmgr node.
       Beware, this list will include any existing IHS nodes."""
    m = "listNodes:"
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    result = []
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        if not nodeIsDmgr(nodename):
            result.append(nodename)
    if 0 == len(result):
        sop(m,"Warning. No non-manager nodes are defined!!!")
    return result

def listUnclusteredServers():
    """Return a list of app servers that don't belong to clusters, as a list of lists
    (see listServersOfType)"""
    allServers = listServersOfType('APPLICATION_SERVER')
    result = []
    for (nodename,servername) in allServers:
        server_id = getServerByNodeAndName(nodename,servername)
        clusterName = AdminConfig.showAttribute(server_id, 'clusterName')
        if clusterName == None:
            result.append([nodename,servername])
    return result

def getServerByNodeAndName( nodename, servername ):
    """Return config id for a server"""
    return getObjectByNodeAndName( nodename, 'Server', servername )

def getObjectByNodeAndName( nodename, typename, objectname ):
    """Get the config object ID of an object based on its node, type, and name"""
    # This version of getObjectByName distinguishes by node,
    # which should disambiguate some things...
    node_id = getNodeId(nodename)
    all = _splitlines(AdminConfig.list( typename, node_id ))
    result = None
    for obj in all:
        name = AdminConfig.showAttribute( obj, 'name' )
        if name == objectname:
            if result != None:
                raise "FOUND more than one %s with name %s" % ( typename, objectname )
            result = obj
    return result
               
def nodeIsUnmanaged( nodename ):
    """Return true if the node is an unmanaged node."""
    return not nodeHasServerOfType( nodename, 'NODE_AGENT' )
    
def syncall():
    m = "wsadminlib.syncall"
    """Sync config to all nodes - return 0 on success, non-zero on error"""
    print "Sync all node start..."
    returncode = 0

    nodenames = listNodes()
    for nodename in nodenames:
        # Note: listNodes() doesn't include the dmgr node - if it did, we'd
        # have to skip itn
        # We do, however, have to skip unmanaged nodes.  These will show up
        # when there is a web server defined on a remote machine.
        if not nodeIsDmgr( nodename ) and not nodeIsUnmanaged( nodename ):
            sop(m,"Sync config to node %s" % nodename)
            Sync1 = AdminControl.completeObjectName( "type=NodeSync,node=%s,*" % nodename )
            if Sync1:
                rc = AdminControl.invoke( Sync1, 'sync' )
                if rc != 'true':  # failed
                    sop(m,"Sync of node %s FAILED" % nodename)
                    returncode = 1
            else:
                sop(m,"WARNING: was unable to get sync object for node %s - is node agent running?" % nodename)
                returncode = 2
    if returncode != 0:
        sop(m,"Syncall FAILED")
    sop(m,"Done")
    return returncode
    
DEBUG_SOP=1

def sop(methodname,message):
    """Prints the specified method name and message with a nicely formatted timestamp.
    (sop is an acronym for System.out.println() in java)"""
    global DEBUG_SOP
    if(DEBUG_SOP):
        timestamp = getSopTimestamp()
        print "%s %s %s" % (timestamp, methodname, message)

def getSopTimestamp():
    """Returns the current system timestamp in a nice internationally-generic format."""
    # Assemble the formatting string in pieces, so that some code libraries do not interpret
    # the strings as special keywords and substitute them upon extraction.
    formatting_string = "[" + "%" + "Y-" + "%" + "m" + "%" + "d-" + "%" + "H" + "%" + "M-" + "%" + "S00]"
    return time.strftime(formatting_string)

def isServerRunning(nodename,servername):
    """Returns a boolean to say if the server is running.
Not 100% accurate but should be close - relies on there only being an mbean for
    a server if it's running"""
    mbean = AdminControl.queryNames('type=Server,node=%s,name=%s,*' % (nodename,servername))
    if mbean:
        return 1
    else :
    	return 0

waitForServerStartSecs = 300
    
def startServer( nodename, servername ):
    """Start the named server - raises exception on error.
    Uses global variable waitForServerStartSeconds"""
    # Check first if it's already running - if we try to start it
    # when it's running, we get an exception and sometimes the
    # try/except below doesn't catch it, I don't know why
    m = "startServer:"
    if isServerRunning(nodename,servername):
        sop(m,"server %s,%s is already running" % (nodename,servername))
    else:
        sop(m,"starting server %s,%s" % (nodename,servername))
        try:
            sop(m,"startServer(%s,%s)" % ( servername, nodename ))
            # optional the 3rd arg is seconds to wait for startup - the default
            # is 1200 (according to 6.1 infocenter) e.g. 20 minutes,
            # which you'd think would be enough for anybody...
            # But it actually doesn't seem to work that way, so put an explicit
            # and long wait time.
            # But if we put 3600, we get a SOAP timeout... going back
            # to 120 for now
            AdminControl.startServer( servername, nodename, 240)

            # Calculate the number of 15-second cycles to wait, minimum 1.
            global waitForServerStartSecs
            waitRetries = waitForServerStartSecs / 15
            if waitRetries < 1:
                waitRetries = 1
            retries = 0
            while not isServerRunning(nodename,servername) and retries < waitRetries:
                sop(m,"server %s,%s not running yet, waiting another 15 secs" % (nodename,servername))
                time.sleep(15)  # seconds
                retries += 1
            if not  isServerRunning(nodename,servername) :
                sop(m,"server %s,%s STILL not running, giving up" % (nodename,servername))
                raise Exception("SERVER FAILED TO START %s,%s" % (nodename,servername))
            else :
            	sop(m,"server %s,%s are running, good luck" % (nodename,servername))

        except:
            # Fails if server already started - ignore it
            ( exception, parms, tback ) = sys.exc_info()
            if -1 != repr( parms ).find( "already running" ):
                return                      # ignore it
            # Some other error? scream and shout
            sop(m,"EXCEPTION STARTING SERVER %s" % servername)
            sop(m,"Exception=%s\nPARMS=%s" % ( str( exception ), repr( parms ) ))
            raise Exception("EXCEPTION STARTING SERVER %s: %s %s" % (servername, str(exception),str(parms)))

def startCluster( clustername ):
    """Start the named server cluster"""
    m = "startCluster:"
    sop(m,"Start cluster %s" % clustername)
    cellname = getCellName()    # e.g. 'poir1Cell01'
    cluster = AdminControl.completeObjectName( 'cell=%s,type=Cluster,name=%s,*' % ( cellname, clustername ) )
    state = AdminControl.getAttribute( cluster, 'state' )
    if state != 'websphere.cluster.partial.start' and state != 'websphere.cluster.running':
        AdminControl.invoke( cluster, 'start' )
    # Wait for it to start
    maxwait = 300  # wait about 5 minutes at most
    count = 0
    sop(m,"wait for cluster %s to start" % clustername)
    while state != 'websphere.cluster.running':
        time.sleep( 30 )
        state = AdminControl.getAttribute( cluster, 'state' )
        sop(m,"state of %s: %s" % ( clustername, state ))
        count += 1
        if count > ( maxwait / 30 ):
            sop(m,"Giving up")
            break
            
def startApplication(appname):
    """Start the named application on all its servers.

    Note: This method assumes the application is installed on all servers.
    To start an application on an individual server, use startApplicationOnServer()
    To start an application on all members of a cluster, use startApplicationOnCluster()"""
    m = "startApplication:"
    sop(m,"Entry. appname=%s" % ( appname ))
    cellname = getCellName()
    servers = listServersOfType('APPLICATION_SERVER')
    for (nodename,servername) in servers:
        sop(m,"Handling cellname=%s nodename=%s servername=%s" % ( cellname, nodename, servername ))
        # Get the application manager MBean
        appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
        # start it
        sop(m,"Starting appname=%s" % ( appname ))
        AdminControl.invoke(appManager, 'startApplication', appname)
        # FIXME: not working on Base unmanaged server on z/OS for some reason
        # Not sure if it works anywhere since usually I just start the
        # servers after configuration and don't need to explicitly start
        # the applications
    sop(m,"Exit.")

def isApplicationRunning(appname):
    """Returns a boolean which indicates whether the application is running.
    see http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.nd.doc/info/ae/ae/txml_adminappobj.html """
    mbean = AdminControl.queryNames('type=Application,name=%s,*' % ( appname ))
    if mbean:
        return 1
    return 0
    
def startApplicationOnServer(appname,nodename,servername):
    """Start the named application on one servers"""
    m = "startApplicationOnServer:"
    sop(m,"Entry. appname=%s nodename=%s servername=%s" % ( appname,nodename,servername ))
    cellname = getCellName()
    # Get the application manager MBean
    appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
    sop(m,"appManager=%s" % ( repr(appManager) ))
    # start it
    rc = AdminControl.invoke(appManager, 'startApplication', appname)
    sop(m,"Exit. rc=%s" % ( repr(rc) ))
    
def stopApplicationOnServer(appname,nodename,servername):
    """Stop the named application on one servers"""
    m = "stopApplicationOnServer:"
    sop(m,"Entry. appname=%s nodename=%s servername=%s" % ( appname,nodename,servername ))
    cellname = getCellName()
    # Get the application manager MBean
    appManager = AdminControl.queryNames('cell=%s,node=%s,type=ApplicationManager,process=%s,*' %(cellname,nodename,servername))
    sop(m,"appManager=%s" % ( repr(appManager) ))
    # start it
    rc = AdminControl.invoke(appManager, 'stopApplication', appname)
    sop(m,"Exit. rc=%s" % ( repr(rc) ))   

def listServersInCluster(clusterName):
    """Return a list of all servers (members) that are in the specified cluster"""
    m = "listServersInCluster:"
    sop(m,"clusterName = %s" % clusterName)
    clusterId = AdminConfig.getid("/ServerCluster:" + clusterName + "/")
    clusterMembers = _splitlines(AdminConfig.list("ClusterMember", clusterId ))
    return clusterMembers
    
def startApplicationOnCluster(appname,clustername):
    """Start the named application on all servers in named cluster"""
    m = "startApplicationOnCluster:"
    sop(m,"Entry. appname=%s clustername=%s" % ( appname, clustername ))
    server_id_list = listServersInCluster( clustername )
    for server_id in server_id_list:
        nodename = AdminConfig.showAttribute( server_id, "nodeName" )
        servername = AdminConfig.showAttribute( server_id, "memberName" )
        sop(m, "Starting application. application=%s cluster=%s node=%s server=%s" % (appname, clustername, nodename, servername) )
        startApplicationOnServer(appname,nodename,servername)
    sop(m,"Exit.")
    
def stopApplicationOnCluster(appname,clustername):
    """Stop the named application on all servers in named cluster"""
    m = "stopApplicationOnCluster:"
    sop(m,"Entry. appname=%s clustername=%s" % ( appname, clustername ))
    server_id_list = listServersInCluster( clustername )
    for server_id in server_id_list:
        nodename = AdminConfig.showAttribute( server_id, "nodeName" )
        servername = AdminConfig.showAttribute( server_id, "memberName" )
        sop(m, "Starting application. application=%s cluster=%s node=%s server=%s" % (appname, clustername, nodename, servername) )
        stopApplicationOnServer(appname,nodename,servername)
    sop(m,"Exit.")
################################################################
# Declare Java classes for getting property pairs from props file
#################################################################
def loadProperties ( propFileName ):
        print "loading prop file "+propFileName
        from java.io import FileInputStream
        from java.util import Properties

        fileprop = Properties(  ) #?PROBLEM? (jacl 10) JAVA::NEW Properties might require:  from ?? import Properties
        fileStream = FileInputStream( propFileName ) #?PROBLEM? (jacl 11) JAVA::NEW FileInputStream might require:  from ?? import FileInputStream

        _J2J_file_ = open(fileStream)
        _J2J_lines_ = _J2J_file_.readlines()
        fileprop = {} 
        for _J2J_line_ in _J2J_lines_:
                _J2J_line_ = _J2J_line_.strip()
                if(len(_J2J_line_)==0 or _J2J_line_[0:1]=="#"): continue
                _J2J_index_ = _J2J_line_.find("=")
                fileprop[_J2J_line_[0:_J2J_index_]] = _J2J_line_[_J2J_index_+1:]
        #endFor (read of propertyFile=fileStream into variable=fileprop)
        _J2J_file_.close()

        return fileprop
#endDef 

def installApplication( filename, servers, clusternames, options ):
    """Install application and map to the named servers/clusters
    with the given options.

    "servers" is a list of dictionaries, each specifying a 'nodename'
    and 'servername' for one server to map the app to.

    "clusternames" is a list of cluster names to map the app to.


    options can be None, or else a list of additional options to pass.
    E.g. ['-contextroot', '/b2bua']
    See the doc for AdminApp.install for full details.
    """
    m = "installApplication:"

    sop(m,"filename=%s, servers=%s, clusternames=%s, options=%s" % (filename,repr(servers),repr(clusternames),options))
    targets = []
    cellname = getCellName()
    if servers != None:
    	for server in servers:
        	targets.append("WebSphere:cell=%s,node=%s,server=%s" % (cellname, server['nodename'], server['servername']))
    if clusternames != None:
    	for clustername in clusternames:
        	targets.append("WebSphere:cell=%s,cluster=%s" % (cellname,clustername))

    target = "+".join( targets )
    print target

    arglist = ['-target', target, ]

    # Set a default virtual host mapping if the caller does not specify one.
    if options != None:
        if not "-MapWebModToVH" in options:
        	virhosttmp = checkVirtualHost(virtual_host)
        	print virhosttmp
        	if virhosttmp == 1:
            		arglist.extend( ['-MapWebModToVH', [['.*', '.*', virtual_host ]]] )
            	else:
			print "virtual_host: This virtual_host can not be found in current Dmgr env..."
			sys.exit()

    # Append caller-specified options.
    if options != None:
        arglist.extend(options)
    sop(m,"Calling AdminApp.install of %s with arglist = %s" % ( filename, repr(arglist) ))
    AdminApp.install( filename, arglist )
#endDef 

def getAdminAppViewValue(appname, keyname, parsename):
    """This helper method returns the value for the specified application
    and key name, as fetched by AdminApp.view().

    Parms: appname - the name of the application
           keyname - the name of the app parameter, eg CtxRootForWebMod
           parsename - the string used to parse results, eg Context Root:
    For example, getAdminApp.view('wussmaster',"-CtxRootForWebMod","Context Root:")

    This method is useful because AdminApp.view() returns a verbose
    multi-line string intended for human viewing and consumption, for example:
        CtxRootForWebMod: Specify the Context root of web module

        Configure values for context roots in web modules.

        Web module:  wussmaster
        URI:  wussmaster.war,WEB-INF/web.xml
        Context Root:  wussmaster
    This method returns a short string useful programmatically.

    Returns None if trouble is encountered."""
    m = "getAdminAppViewValue:"
    sop(m,"Entry. appname=%s keyname=%s parsename=%s" % ( appname, keyname, parsename ))

    # Fetch a verbose human-readable string from AdminApp.view()
    verboseString = AdminApp.view(appname, [keyname])
    sop(m,"verboseString=%s" % ( verboseString ))
    verboseStringList = _splitlines(verboseString)
    for str in verboseStringList:
        #sop("","str=>>>%s<<<" % ( str ))
        if str.startswith(parsename):
            resultString = str[len(parsename):].strip()
            sop(m,"Exit. Found value. Returning >>>%s<<<" % ( resultString ))
            return resultString

    sop(m,"Exit. Did not find value. Returning None.")
    return None

def getApplicationContextRoot(appname):
    """Returns the context root value for the specified application.
    Returns None if trouble is encountered."""
    return getAdminAppViewValue(appname, "-CtxRootForWebMod", "Context Root:")
    
def getDmgrNode():
    """Return config id of the Dmgr node"""
    node_ids = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in node_ids:
        nodename = getNodeName(node_id)
        if nodeIsDmgr(nodename):
            return node_id
    return None
    
def getDmgrNodeName():
    """Return node name of the Dmgr node"""
    return getNodeName(getDmgrNode())

base_nd_flag = ""
def isND():
    """Are we connected to a ND system"""
    global base_nd_flag
    if base_nd_flag == "":
        _whatEnv()
    return base_nd_flag == 'nd'

def _whatEnv():
    """Not user callable
    Sets some flags that other things use"""
    m = "_whatEnv:"


    global base_nd_flag
    base_nd_flag = whatEnv()

def whatEnv():
    """Returns 'nd' if connected to a dmgr, 'base' if connected to
    an unmanaged server, and 'other' if connected to something else
    (which shouldn't happen but could)"""
    m = "whatEnv:"

    # Simpler version - should work whether connected or not
    servers = getObjectsOfType('Server')
    for server in servers:
        servertype = getObjectAttribute(server, 'serverType')
        if servertype == 'DEPLOYMENT_MANAGER':
            return 'nd'  # we have a deployment manager
    return 'base'  # no deployment manager, must be base

def compareIntLists(a, b):
    """Compares two python lists containing ints.

       Returns -1 if array a sorts before array b.
       Returns 0 if they're the same.
       Returns +1 if array a sorts after array b.

       This method was ported from FritzUtils.java"""
    m = "compareIntArrays:"
    # sop(m,"Entry. a=%s b=%s" % ( a, b, ))

    i = 0
    while (i<len(a) and i<len(b)):
        if (a[i] < b[i]):
            # sop(m,"Exit 1. a[i]<b[i]. i=%i a[i]=%i b[i]=%i" % ( i, a[i], b[i] ))
            return -1
        if (a[i] > b[i]):
            # sop(m,"Exit 2. a[i]>b[i]. i=%i a[i]=%i b[i]=%i" % ( i, a[i], b[i] ))
            return 1
        # No decision yet.
        i = i + 1
    # So far, still the same... is one longer? it goes later.
    if (len(a) < len(b)):
        # sop(m,"Exit 3. len(a)<len(b). len(a)=%i len(b)=%i" % ( len(a), len(b) ))
        return -1
    if (len(a) > len(b)):
        # sop(m,"Exit 4. len(a)>len(b). len(a)=%i len(b)=%i" % ( len(a), len(b) ))
        return -1
    # sop(m,"Exit 5. a=b. Returning zero.")
    return 0;

def parseVersion(stringVersion):
    """Parses a version string like "6.1.0.3" and
       returns a python list of ints like [ 6,1,0,3 ]

       This method was ported from FritzUtils.java"""
    m = "parseVersion:"
    # sop(m,"Entry. stringVersion=%s" % ( stringVersion ))
    listVersion = []
    parts = stringVersion.split('.')
    for part in parts:
        # sop(m,"Adding part=%s" % part)
        listVersion.append(int(part))
    # sop(m,"Exit. Returning listVersion=%s" % ( listVersion ))
    return listVersion
        
def versionAtLeast(nodename, stringVersion):
    """Returns true if the version we're running is greater than or equal to the version passed in.

       For example, pass in '6.1.0.13.
       If we're running 6.1.0.13, or 7.0.0.0, it returns true.
       If we're running 6.1.0.12, it returns false.

       This method was ported from FritzUtils.java"""

    # m = "versionAtLeast:"
    # sop(m,"Entry. nodename=%s stringVersion=%s" % (nodename,stringVersion))
    x = compareIntLists(parseVersion(getNodeVersion(nodename)),parseVersion(stringVersion))
    # sop(m,"Exit. x=%i Returning %s" % ( x, (x>=0) ))
    return (x >= 0)

def getNodeVersion(nodename):
    """Return the WebSphere version of the node - e.g. "6.1.0.0"  - only we're connected
    to a running process.
    If we ever need it to work when server is not running, we can get at least
    minimal information from the node-metadata.properties file in the node's
    config directory."""
    sop("getNodeVersion:", "AdminTask.getNodeBaseProductVersion('[-nodeName %s]')" %  nodename )
    version = AdminTask.getNodeBaseProductVersion(  '[-nodeName %s]' %  nodename   )
    return version

def getNodePlatformOS(nodename):
    """Get the OS of the named node (not sure what format it comes back in).
    Some confirmed values: 'linux', 'windows', 'os390', 'solaris', 'hpux'
    I think these come from node-metadata.properties, com.ibm.websphere.nodeOperatingSystem;
    on that theory, AIX should return 'aix'.
    """
    return AdminTask.getNodePlatformOS('[-nodeName %s]' % nodename)
    
def getNodeNameList(platform=None,servertype=None):
    """Returns a list with node names which match the specified platform and server type.
    Parameter 'platform' may be linux, windows, os390, etc. It defaults to return all platforms.
    Parameter 'servertype' may be APPLICATION_SERVER, PROXY_SERVER, etc. It defaults to all types.
    For example, this returns a list of proxies on hpux:
        hpuxProxyList = getNodeNameList(platform='hpux',servertype='PROXY_SERVER')
    """
    m = "getNodeNameList: "
    #sop(m,"Entry. platform=%s servertype=%s" % ( platform, servertype ))

    nodelist = []
    serverlist = listServersOfType(servertype)
    #sop(m,"serverlist=%s" % ( repr(serverlist) ))
    for (nodename,servername) in serverlist:
        actual_platform = getNodePlatformOS(nodename)
        #sop(m,"nodename=%s servername=%s actual_platform=%s" % ( nodename, servername, actual_platform ))
        if None == platform or actual_platform == platform:
            if nodename not in nodelist:
                nodelist.append(nodename)
                #sop(m,"Saved node")

    #sop(m,"Exit. Returning nodelist=%s" % ( repr(nodelist) ))
    return nodelist

        
def listServerClusters():
    """Return list of names of server clusters"""
    cluster_ids = _splitlines(AdminConfig.list( 'ServerCluster' ))
    cellname = getCellName()
    result = []
    for cluster_id in cluster_ids:
        result.append(AdminConfig.showAttribute(cluster_id,"name"))
    return result
                            
def listApplications():
    """Return list of all application names.
    Note: the admin console is included - it's called 'isclite' in v6.1, don't know on other versions"""
    if isND():
        nodename = getDmgrNodeName()
    else:
        nodename = listNodes()[0]  # there will only be one
    if versionAtLeast(nodename, "6.1.0.0"):
        return _splitlines(AdminApp.list( 'WebSphere:cell=%s' % getCellName() ))
    else:
        # for 6.0.2 support
        return _splitlines(AdminApp.list())

def saveAndSync():
    """Save config changes and sync them - return 0 on sync success, non-zero on failure"""
    m = "save:"
    sop(m, "AdminConfig.queryChanges()")
    changes = _splitlines(AdminConfig.queryChanges())
    for change in changes:
        sop(m, "  "+change)
    rc = 0;
    AdminConfig.setSaveMode("overwriteOnConflict")
    sop(m, "AdminConfig.getSaveMode()")
    mode = AdminConfig.getSaveMode()

    sop(m, "  "+mode)
    sop(m, "AdminConfig.save()")
    AdminConfig.save()
    sop(m, "  Save complete!")
    rc = syncall()
    return rc
    
def updateApplication(appname,filename):
    """Update an application with a new ear file"""
    # We need to know the application name - it's in an xml file
    # in the ear
   	#added by lwm 
    if earFileLocationLower.endswith(".zip"):
			AdminApp.update(appname,            # name of application
	                    'partialapp',              # type of update to do  
	                    # options:
	                    ['-contents', filename,
	                     ],
	                    )
    else:
      AdminApp.update(appname,            # name of application
	                     'app',              # type of update to do
	                    # options:
	                    ['-operation', 'update', # redundant but required
	                    '-contents', filename,
	                    ],
	                    )
    
def deleteApplicationByName( name ):
    """Delete the named application from the cell"""
    AdminApp.uninstall( name )

def getServerClusterByName( name ):
    """Return the config object id for the named server cluster
    TODO: get rid of either this or getClusterId"""
    return getObjectByName( 'ServerCluster', name )

def getObjectByName( typename, objectname ):
    """Get an object of a given type and name - WARNING: the object should be unique in the cell; if not, use getObjectByNodeAndName instead."""
    all = _splitlines(AdminConfig.list( typename ))
    result = None
    for obj in all:
        name = AdminConfig.showAttribute( obj, 'name' )
        if name == objectname:
            if result != None:
                raise "FOUND more than one %s with name %s" % ( typename, objectname )
            result = obj
    return result

def deleteApplicationByNameIfExists( applicationName ):
    """Delete the application if it already exists.

    Return true (1) if it existed and was deleted.
    Return false (0) if it did not exist."""
    m = "deleteApplicationByNameIfExists:"
    sop(m,"Application Name = %s" % applicationName)
    apps = listApplications()
    sop(m,repr(apps))
    if applicationName in apps:
        sop(m,"Removing Application: %s" % repr(applicationName))
        deleteApplicationByName(applicationName)
        # Did exist and has been deleted, return true (1)
        return 1
    # Did not exist, did not delete, return false (0)
    return 0

def restartServer( nodename, servername, maxwaitseconds, ):

    m = "restartServer: "
    sop(m,"Entry. nodename=%s servername=%s maxwaitseconds=%d" % (nodename, servername, maxwaitseconds, ))

    if not isServerRunning( nodename, servername ):
        raise m + "ERROR: Server is not already running. nodename=%s servername=%s" % (nodename, servername, )
    sop(m,"Server %s is running." % ( servername, ))

    # Get the server mbean
    serverObjectName = AdminControl.completeObjectName('type=Server,node=%s,process=%s,*' % ( nodename, servername ,))
    sop(m,"Invoking restart on server. serverObjectName=%s" % ( serverObjectName, ))

    # Restart the server.
    AdminControl.invoke(serverObjectName, 'restart')

    # Wait up to a max timeout if requested by the caller.
    elapsedtimeseconds = 0
    if maxwaitseconds > 0:
        sleeptimeseconds = 1

        # Phase 1 - Wait for server to stop (This can take 30 seconds on a reasonably fast linux intel box)
        isRunning = isServerRunning( nodename, servername )
        while isRunning and elapsedtimeseconds < maxwaitseconds:
            sop(m,"Waiting %d of %d seconds for %s to stop. isRunning=%s" % ( elapsedtimeseconds, maxwaitseconds, servername, isRunning, ))
            time.sleep( sleeptimeseconds )
            elapsedtimeseconds = elapsedtimeseconds + sleeptimeseconds
            isRunning = isServerRunning( nodename, servername )

        # Phase 2 - Wait for server to start (This can take another minute)
        while not isRunning and elapsedtimeseconds < maxwaitseconds:
            sop(m,"Waiting %d of %d seconds for %s to restart. isRunning=%s" % ( elapsedtimeseconds, maxwaitseconds, servername, isRunning, ))
            time.sleep( sleeptimeseconds )
            elapsedtimeseconds = elapsedtimeseconds + sleeptimeseconds
            isRunning = isServerRunning( nodename, servername )

    isRunning = isServerRunning( nodename, servername )
    sop(m,"Exit. nodename=%s servername=%s maxwaitseconds=%d elapsedtimeseconds=%d Returning isRunning=%s" % (nodename, servername, maxwaitseconds, elapsedtimeseconds, isRunning ))
    return isRunning
    
def stopCluster( clustername ):
    """Stop the named server cluster"""
    m = "stopCluster:"
    sop(m,"Stop cluster %s" % clustername)
    cellname = getCellName()    # e.g. 'poir1Cell01'
    cluster = AdminControl.completeObjectName( 'cell=%s,type=Cluster,name=%s,*' % ( cellname, clustername ) )
    state = AdminControl.getAttribute( cluster, 'state' )
    if state != 'websphere.cluster.partial.stop' and state != 'websphere.cluster.stopped':
        AdminControl.invoke( cluster, 'stop' )
    # Wait for it to stop
    maxwait = 300  # wait about 5 minutes at most
    count = 0
    sop(m,"wait for cluster %s to stop" % clustername)
    while state != 'websphere.cluster.stopped':
        time.sleep( 30 )
        state = AdminControl.getAttribute( cluster, 'state' )
        sop(m,"state of %s: %s" % ( clustername, state ))
        count += 1
        if count > ( maxwait / 30 ):
            sop(m,"Giving up")
            break
            


def getNodePlatformOS(nodename):
    """Get the OS of the named node (not sure what format it comes back in).
    Some confirmed values: 'linux', 'windows', 'os390', 'solaris', 'hpux'
    I think these come from node-metadata.properties, com.ibm.websphere.nodeOperatingSystem;
    on that theory, AIX should return 'aix'.
    """
    return AdminTask.getNodePlatformOS('[-nodeName %s]' % nodename)

def getNodeHostname(nodename):
    """Get the hostname of the named node"""
    return AdminConfig.showAttribute(getNodeId(nodename),'hostName')
        
def serverStatus():
    """Display the status of all nodes, servers, clusters..."""
    print "Server status"
    print "============="

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        if nodeIsDmgr(nodename):
            print "NODE %s on %s (%s) - Deployment manager" % (nodename,hostname,platform)
        else:
            print "NODE %s on %s (%s)" % (nodename,hostname,platform)
            serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
            for serverEntry in serverEntries:
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                isRunning = isServerRunning(nodename,sName)
                if isRunning: status = "running"
                else: status = "stopped"
                print "\t%-18s %-15s %s" % (sType,sName,status)

    appnames = listApplications()
    print "APPLICATIONS:"
    for a in appnames:
        if a != 'isclite' and a != 'filetransfer':
            print "\t%s" % a
            
def restartNodeagent( nodename, servername):

    m = "restartServer: "
    sop(m,"Entry. nodename=%s servername=%s " % (nodename, servername, ))

    if isServerRunning( nodename, servername ):
#        raise m + "ERROR: Server is not already running. nodename=%s servername=%s" % (nodename, servername, )
#    sop(m,"Server %s is running." % ( servername, ))

    # Get the server mbean
    	serverObjectName = AdminControl.completeObjectName('type=Server,node=%s,process=%s,*' % ( nodename, servername ,))
    	sop(m,"Invoking restart on server. serverObjectName=%s" % ( serverObjectName, ))

    # Restart the server.
    	AdminControl.invoke(serverObjectName, 'restart')

def nodeagentStatus():
    """Display the status of all nodes..."""
    print "Server status"
    print "============="

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        if nodeIsDmgr(nodename):
            print "NODE %s on %s (%s) - Deployment manager" % (nodename,hostname,platform)
        else:
            print "NODE %s on %s (%s)" % (nodename,hostname,platform)
            serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
            for serverEntry in serverEntries:
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                if (sType == "NODE_AGENT"):
                	isRunning = isServerRunning(nodename,sName)
                	if isRunning: status = "running"
                	else: status = "stopped"
                	print "\t%-18s %-15s %s" % (sType,sName,status)

def restartAllNodeagent():
    """restart all nodes..."""

    nodes = _splitlines(AdminConfig.list( 'Node' ))
    for node_id in nodes:
        nodename = getNodeName(node_id)
        hostname = getNodeHostname(nodename)
        platform = getNodePlatformOS(nodename)
        
        print "NODE %s on %s (%s)" % (nodename,hostname,platform)
        
        serverEntries = _splitlines(AdminConfig.list( 'ServerEntry', node_id ))
        for serverEntry in serverEntries:
        	
                sName = AdminConfig.showAttribute( serverEntry, "serverName" )
                sType = AdminConfig.showAttribute( serverEntry, "serverType" )
                if (sType == "NODE_AGENT"):
                	isRunning = isServerRunning(nodename,sName)
                	if isRunning: status = "running"
                	else: status = "stopped"
                	print "\t%-18s %-15s %s" % (sType,sName,status)
                	restartNodeagent(nodename,"nodeagent")
                	

def isGlobalSecurityEnabled():
    """ Check if Global Security is enabled. If security is enabled return True else False"""
    m = "isGlobalSecurityEnabled"
    sop(m,"Entry: Checking if Global Security is enabled...")
    securityon = AdminTask.isGlobalSecurityEnabled()
    sop(m,"Global Security enabled: %s" % (securityon))
    return securityon

def _getSecurityId():
    global AdminControl, AdminConfig
    cellName = getCellName()
    try:
        param = "/Cell:" + cellName + "/Security:/"
        secId = AdminConfig.getid(param)
        if len(secId) == 0:
            print "Security ConfigId was not found"
            return None

        #print "Got Security ConfigId is " + secId
        return secId
    except:
        print "AdminConfig.getid(%s) caught an exception" % param
        return None


#appServers = ["server1","server2"]


############################################
#  Modify webcontainerProperties Settings  #
############################################
def configWebContainerProperties(serverName):
    print " Modifying Application Server "+serverName+" 's webcontainerProperties Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    webcontainer = AdminConfig.list("WebContainer",server)
    
    #print AdminConfig.showall(webcontainer)

    for x in webcontainerProperties:
	name = ["name",x[0]]
	value = ["value",x[1]]
	requesed = x[2]
	if requesed == "":
		customPropAttrs = [name, value]
	else:
		requesed=["required",requesed]
		customPropAttrs = [name, value,requesed]
	#print customPropAttrs
    	AdminConfig.create("Property", webcontainer, customPropAttrs)
    	#print x
    
    AdminConfig.save()
    
    print " Finished Successfully"
#endDef

###########################################
#    Modify systemProperties Settings     #
###########################################
def configJVMSystemProperties(serverName):
    print " Modifying Application Server "+serverName+" 's JVMSystemProperties Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    for x in systemProperties:
	name = ["name",x[0]]
	value = ["value",x[1]]
	requesed = x[2]
	if requesed == "":
		customPropAttrs = [name, value]
	else:
		requesed=["required",requesed]
		customPropAttrs = [name, value,requesed]
	#print customPropAttrs
    	AdminConfig.create("Property", jvmEntries, customPropAttrs)
    	#print x
    
    AdminConfig.save()
    
    print " Finished Successfully"
#endDef

###########################################
#      Modify environment Settings        #
###########################################
def configEnvironment(serverName):
    print " Modifying Application Server "+serverName+" 's environment Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    JavaProcessDef = AdminConfig.list("JavaProcessDef",server)
    for x in environment:
	name = ["name",x[0]]
	value = ["value",x[1]]
	requesed = x[2]
	if requesed == "":
		customPropAttrs = [name, value]
	else:
		requesed=["required",requesed]
		customPropAttrs = [name, value,requesed]
	#print customPropAttrs
    	AdminConfig.create("Property", JavaProcessDef, customPropAttrs)
    	#print x
    
    AdminConfig.save()
    
    print " Finished Successfully"
#endDef

###########################################################
#    Modify Administration Custom Properties Settings     #
###########################################################
def configHangCustomProperties(serverName):
    print " Modifying Application Server "+serverName+" 's Hang Custom Properties Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    applicationServer = AdminConfig.list("ApplicationServer",server)

    #jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    propertys=AdminConfig.list("Property",applicationServer)
    if propertys == "":
    		
    	for x in adminCustomProperties:
		name = ["name",x[0]]
		value = ["value",x[1]]
		requesed = x[2]
		if requesed == "":
			customPropAttrs = [name, value]
		else:
			requesed=["required",requesed]
			customPropAttrs = [name, value,requesed]
	
	
		AdminConfig.create("Property", applicationServer, customPropAttrs)
    else:
    	ps = wsadminToList(propertys);
    		
	for one in ps:
    		#print one
		if AdminConfig.showAttribute(one,"name") == "com.ibm.websphere.threadmonitor.dump.java":
			AdminConfig.remove(one)
			continue
		if AdminConfig.showAttribute(one,"name") == "com.ibm.websphere.threadmonitor.threshold":
			AdminConfig.remove(one)
			continue
    	
	for x in adminCustomProperties:
		name = ["name",x[0]]
		value = ["value",x[1]]
		requesed = x[2]
		if requesed == "":
			customPropAttrs = [name, value]
		else:
			requesed=["required",requesed]
			customPropAttrs = [name, value,requesed]
	
	
		AdminConfig.create("Property", applicationServer, customPropAttrs)
		
    	#print x
    print AdminConfig.list("Property",applicationServer)
    
    AdminConfig.save()
    
    print " Finished Successfully"
#endDef

###########################################
#       Modify jvmEntries Settings        #
###########################################
def configJvmEntries(serverName):
    print " Modifying Application Server "+serverName+" 's jvmEntries Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    
    #print AdminConfig.showall(jvmEntries)

    Attribute1 = ["initialHeapSize", jvmEntries_initialHeapSize]
    Attribute2 = ["maximumHeapSize", jvmEntries_maximumHeapSize]
    Attribute3 = ["verboseModeClass", jvmEntries_verboseModeClass]
    Attribute4 = ["verboseModeGarbageCollection", jvmEntries_verboseModeGarbageCollection]
    Attribute5 = ["verboseModeJNI", jvmEntries_verboseModeJNI]
    Attribute6 = ["debugMode", jvmEntries_debugMode]
    Attribute7 = ["genericJvmArguments", jvmEntries_genericJvmArguments]
    Attribute8 = ["runHProf", jvmEntries_runHProf]
  
    Attributes = [Attribute1,Attribute2,Attribute3,Attribute4,Attribute5,Attribute6,Attribute7,Attribute8]

    AdminConfig.modify(jvmEntries, Attributes)
        
    AdminConfig.save( )
    print " Finished Successfully"
#endDef


def configGCEntries(serverName):
    print " Modifying Application Server "+serverName+" 's GCEntries Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    
    #print AdminConfig.showall(jvmEntries)

    Attribute1 = ["verboseModeGarbageCollection", jvmEntries_verboseModeGarbageCollection]
    
    jvmStr = AdminConfig.showAttribute(jvmEntries, "genericJvmArguments" )
    #print jvmStr
    #print jvmStr.find("ConnLeakLogic=finest")
    if -1 == jvmStr.find("-Xverbosegclog:${SERVER_LOG_ROOT}/gc#.log,10,10000"):
    	jvmStr = jvmStr + " -Xverbosegclog:${SERVER_LOG_ROOT}/gc#.log,10,10000"
    
    Attribute2 = ["genericJvmArguments", jvmStr]

    Attributes = [Attribute1,Attribute2]

    AdminConfig.modify(jvmEntries, Attributes)
       
    #print AdminConfig.showall(jvmEntries)
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

def configXdumpBigObjEntries(serverName):
    print " Modifying Application Server "+serverName+" 's Xdump agent for Big Object Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    
    #print AdminConfig.showall(jvmEntries)
    
    jvmStr = AdminConfig.showAttribute(jvmEntries, "genericJvmArguments" )
    #print jvmStr
    #print jvmStr.find("ConnLeakLogic=finest")
    if -1 == jvmStr.find("-Xdump:stack:events=allocation,filter=#5m"):
    	jvmStr = jvmStr + " -Xdump:stack:events=allocation,filter=#5m"
    
    Attribute2 = ["genericJvmArguments", jvmStr]

    Attributes = [Attribute2]

    AdminConfig.modify(jvmEntries, Attributes)
       
    #print AdminConfig.showall(jvmEntries)
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

def configXdumCoreFileEntries(serverName):
    print " Modifying Application Server "+serverName+" 's Xdump agent for Core File Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    jvmEntries = AdminConfig.list("JavaVirtualMachine",server)
    
    #print AdminConfig.showall(jvmEntries)
    
    jvmStr = AdminConfig.showAttribute(jvmEntries, "genericJvmArguments" )
    #print jvmStr
    #print jvmStr.find("ConnLeakLogic=finest")
    if -1 == jvmStr.find("-Xdump:system:events=systhrow,filter=java/lang/OutOfMemoryError"):
    	if -1 == jvmStr.find("core."):
    		if -1 == jvmStr.find(".dmp"):
    			jvmStr = jvmStr + " -Xdump:system:events=systhrow,filter=java/lang/OutOfMemoryError,range=1..1,priority=999,file=${USER_INSTALL_ROOT}/core.%Y%m%d.%H%M%S.%pid.%seq.dmp"
    
    Attribute2 = ["genericJvmArguments", jvmStr]

    Attributes = [Attribute2]

    AdminConfig.modify(jvmEntries, Attributes)
       
    #print AdminConfig.showall(jvmEntries)
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#    Modify monitoringPolicy Settings     #
###########################################
def configMonitoringPolicy(serverName):
    print " Modifying Application Server "+serverName+" 's monitoringPolicy Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    processDefinitions = AdminConfig.list("JavaProcessDef",server)
    
    monitoringPolicy = AdminConfig.showAttribute(processDefinitions,"monitoringPolicy")
    #print AdminConfig.showall(monitoringPolicy)
    Attribute1 = ["autoRestart", monitoringPolicy_autoRestart]
    Attribute2 = ["maximumStartupAttempts", monitoringPolicy_maximumStartupAttempts]
    Attribute3 = ["nodeRestartState", monitoringPolicy_nodeRestartState]
    Attribute4 = ["pingInterval", monitoringPolicy_pingInterval]
    Attribute5 = ["pingTimeout", monitoringPolicy_pingTimeout]
    
    Attributes = [Attribute1,Attribute2,Attribute3,Attribute4,Attribute5]

    AdminConfig.modify(monitoringPolicy, Attributes)
        
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#  	   Modify stderr Settings         #
###########################################
def configStderr(serverName):
    print " Modifying Application Server "+serverName+" 's stderr Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    #print AdminConfig.showall(processDefinitions)
    
    ioRedirect = AdminConfig.showAttribute(processDefinitions,"ioRedirect")
    #print AdminConfig.showall(ioRedirect)

    transactionAttribute1 = ["stderrFilename", stderrFilename]
    
    transactionAttributes = [transactionAttribute1]

    AdminConfig.modify(ioRedirect, transactionAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#  	   Modify stdout Settings         #
###########################################
def configStdout(serverName):
    print " Modifying Application Server "+serverName+" 's stdout Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    processDefinitions = AdminConfig.list("JavaProcessDef",server)

    #print AdminConfig.showall(processDefinitions)
    
    ioRedirect = AdminConfig.showAttribute(processDefinitions,"ioRedirect")
    #print AdminConfig.showall(ioRedirect)

    transactionAttribute1 = ["stdoutFilename", stdoutFilename]
    
    transactionAttributes = [transactionAttribute1]

    AdminConfig.modify(ioRedirect, transactionAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#  	   Modify Cookie Settings         #
###########################################
def configCookie(serverName):
    print " Modifying Application Server "+serverName+" 's Cookie Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    #print AdminConfig.list("Cookie",server)
    cookie = AdminConfig.list("Cookie",server)
    
    #print AdminConfig.showall(cookie)

    transactionAttribute1 = ["maximumAge", Cookie_maximumAge]
    transactionAttribute2 = ["secure", Cookie_secure]
    
    transactionAttributes = [transactionAttribute1,transactionAttribute2]

    AdminConfig.modify(cookie, transactionAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef


###########################################
#  	  Modify Session Settings         #
###########################################
def configSession(serverName):
    print " Modifying Application Server "+serverName+" 's Session Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    session = AdminConfig.list("SessionManager",server) 
    #print AdminConfig.showall(session)

    Attribute1 = ["enable", Session_enable]
    Attribute2 = ["enableUrlRewriting", Session_enableUrlRewriting]
    Attribute3 = ["enableCookies", Session_enableCookies]
    Attribute4 = ["enableSSLTracking", Session_enableSSLTracking]
    Attribute5 = ["enableProtocolSwitchRewriting", Session_enableProtocolSwitchRewriting]
    Attribute6 = ["sessionPersistenceMode", Session_sessionPersistenceMode]
    Attribute7 = ["allowSerializedSessionAccess", Session_allowSerializedSessionAccess]
    Attribute8 = ["maxWaitTime", Session_maxWaitTime]
    Attribute9 = ["accessSessionOnTimeout", Session_accessSessionOnTimeout]

    sessionAttributes = [Attribute1,Attribute2,Attribute3,Attribute4,Attribute5,Attribute6,Attribute7,Attribute8,Attribute9]

    AdminConfig.modify(session, sessionAttributes)
    
    tuningParams = AdminConfig.list("TuningParams",session)
    #print tuningParams
    #print AdminConfig.showall(tuningParams)
    
    sessionAttribute11 = ["maxInMemorySessionCount", Session_maxInMemorySessionCount]
    sessionAttribute12 = ["allowOverflow", Session_allowOverflow]
    sessionAttribute13 = ["invalidationTimeout", Session_invalidationTimeout]
    
    sessionAttributes = [sessionAttribute11,sessionAttribute12,sessionAttribute13]
    AdminConfig.modify(tuningParams, sessionAttributes)

    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#  	Modify Transaction Settings       #
###########################################
def configTransaction(serverName):
    print " Modifying Application Server "+serverName+" 's Transaction Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    
    #print AdminConfig.list("TransactionService",server)
    transactionService = AdminConfig.list("TransactionService",server)
    
    #print AdminConfig.showall(transactionService)

    transactionAttribute1 = ["enable", Transaction_enable]
    transactionAttribute2 = ["totalTranLifetimeTimeout", Transaction_totalTranLifetimeTimeout]
    transactionAttribute3 = ["propogatedOrBMTTranLifetimeTimeout", Transaction_propogatedOrBMTTranLifetimeTimeout]
    transactionAttribute4 = ["clientInactivityTimeout", Transaction_clientInactivityTimeout]
    #transactionAttribute5 = ["asyncResponseTimeout", "31"]
    
    transactionAttributes = [transactionAttribute1,transactionAttribute2,transactionAttribute3,transactionAttribute4]

    AdminConfig.modify(transactionService, transactionAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#	 Modify HTTP access Settings      #
###########################################
def configHTTPAccessLog(serverName):
    print " Modifying Application Server "+serverName+" 's HTTPAccessLoggingService Settings....."
    server = AdminConfig.getid("/Server:"+serverName )

    httpAccessLoggingService = AdminConfig.list("HTTPAccessLoggingService", server )
  
    #print httpAccessLoggingService
    #print AdminConfig.showall(httpAccessLoggingService)

    httpTraceAttribute1 = ["enable", HTTPAccess_enable]
    httpTraceAttribute2 = ["enableErrorLogging", HTTPAccess_enableErrorLogging]
    httpTraceAttribute3 = ["enableAccessLogging", HTTPAccess_enableAccessLogging]
    
    httpTraceAttributes = [httpTraceAttribute1,httpTraceAttribute2,httpTraceAttribute3]
    AdminConfig.modify(httpAccessLoggingService, httpTraceAttributes)
    
    errorLog= AdminConfig.showAttribute(httpAccessLoggingService, "errorLog" )
    #print errorLog
    errorLog1 = ["filePath", errorLog_filePath]
    errorLog2 = ["maximumSize", errorLog_maximumSize]
    errorLog3 = ["maximumBackupFiles", errorLog_maximumBackupFiles]
    errorLogAttributes = [errorLog1,errorLog2,errorLog3]
    AdminConfig.modify(errorLog, errorLogAttributes)
    
    accessLog= AdminConfig.showAttribute(httpAccessLoggingService, "accessLog" )
    #print accessLog
    accessLog1 = ["filePath", accessLog_filePath]
    accessLog2 = ["maximumSize", accessLog_maximumSize]
    accessLog3 = ["maximumBackupFiles", accessLog_maximumBackupFiles]
    accessLogAttributes = [accessLog1,accessLog2,accessLog3]
    AdminConfig.modify(accessLog, accessLogAttributes)
    
    print AdminConfig.showall(httpAccessLoggingService)
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

def configWCInboundDefaultAccessLog(serverName):
    print " Modifying Application Server "+serverName+" 's WCInboundDefault AccessLog Settings....."
    server = AdminConfig.getid("/Server:"+serverName )

    listpool = _splitlines(AdminConfig.list("Chain", server ))
    
    item = ""
    for pool in listpool:
       #print  AdminConfig.showall(pool)
       
       if AdminConfig.showAttribute( pool, "name" ) == "WCInboundDefault":
       		item =  AdminConfig.showAttribute(pool , "transportChannels")
       		it = wsadminToList(item)
       		
       		for i in it:
       			if (regexp("HTTP", i) == 1):
       				#print AdminConfig.showall(i);
       				logenable = AdminConfig.showAttribute(i,"enableLogging")
       				
       				attribute1 = ["enableLogging", "true"]
       				attribute2 = ["useChannelAccessLoggingSettings", "true"]
       				attribute3 = ["useChannelErrorLoggingSettings", "true"]
       				
    
    				attributes = [attribute1,attribute2,attribute3]
       				AdminConfig.modify(i, attributes)

       				logid = AdminConfig.list("Property",i)
       				findstr = "0"
       				if logid == "":
       					findstr = "0"
       				else:
       					logidlist = wsadminToList(logid)
       				
       					for x in logidlist:
       						if (regexp("accessLogFormat", x) == 1):
       							findstr = "1"
       							break       				
       				if findstr == "0":
       					varName = ["name", "accessLogFormat"]
    					varValue = ["value", "%h %i %u %t \"%r\" %s %b %D"]
    					customPropAttrs = [varName, varValue]
    					AdminConfig.create("Property", i, customPropAttrs)
    				
    				#print AdminConfig.showall(i)
    				httpllog =  AdminConfig.showAttribute(i,"httpInboundChannelLogging")
    				#print AdminConfig.showAttribute(i,"httpInboundChannelLogging")
    				#print AdminConfig.getObjectType(httpllog)
    				#print AdminConfig.showall(httpllog)
    				
    				httpTraceAttribute1 = ["errorLogLevel", "ERROR"]
				httpTraceAttribute2 = ["enableErrorLogging", "true"]
				httpTraceAttribute3 = ["enableAccessLogging", "true"]
				httpTraceAttribute4 = ["accessLogFormat", "COMBINED"]
				httpTraceAttributes = [httpTraceAttribute1,httpTraceAttribute2,httpTraceAttribute3,httpTraceAttribute4]
				    				
    				if httpllog == None :
    					inlogging = AdminConfig.create("HTTPInboundChannelLogging",i, httpTraceAttributes)
    					
    					errorLog1 = ["filePath", "${SERVER_LOG_ROOT}/error.log"]
    					errorLog2 = ["maximumSize", "10"]
    					errorLog3 = ["maximumBackupFiles", "20"]
    					errorLogAttributes = [errorLog1,errorLog2,errorLog3]
    					AdminConfig.create("LogFile", inlogging,errorLogAttributes,"errorLog")
    					
    					accessLog1 = ["filePath", "${SERVER_LOG_ROOT}/access.log"]
    					accessLog2 = ["maximumSize", "10"]
    					accessLog3 = ["maximumBackupFiles", "20"]
    					accessLogAttributes = [accessLog1,accessLog2,accessLog3]
    					AdminConfig.create("LogFile",inlogging, accessLogAttributes,"accessLog")
    				else:
					AdminConfig.modify(httpllog, httpTraceAttributes)
					
					errorLog= AdminConfig.showAttribute(httpllog, "errorLog" )
					#print AdminConfig.getObjectType(errorLog)
					#print AdminConfig.showall(httpllog)
					
					if errorLog == None:						
    						errorLog1 = ["filePath", "${SERVER_LOG_ROOT}/error.log"]
    						errorLog2 = ["maximumSize", "10"]
    						errorLog3 = ["maximumBackupFiles", "20"]
    						errorLogAttributes = [errorLog1,errorLog2,errorLog3]
    						AdminConfig.create("LogFile",httpllog, errorLogAttributes,"errorLog")
    					else:
    			    			errorLog1 = ["filePath", "${SERVER_LOG_ROOT}/error.log"]
    						errorLog2 = ["maximumSize", "10"]
    						errorLog3 = ["maximumBackupFiles", "20"]
    						errorLogAttributes = [errorLog1,errorLog2,errorLog3]
    						AdminConfig.modify(errorLog, errorLogAttributes)
    					
    					accessLog= AdminConfig.showAttribute(httpllog, "accessLog" )
    					if accessLog == None: 						
    						#print accessLog
    						accessLog1 = ["filePath", "${SERVER_LOG_ROOT}/access.log"]
    						accessLog2 = ["maximumSize", "10"]
    						accessLog3 = ["maximumBackupFiles", "20"]
    						accessLogAttributes = [accessLog1,accessLog2,accessLog3]
    						AdminConfig.create("LogFile",httpllog, accessLogAttributes,"accessLog")
    					else:
        					#print accessLog
    						accessLog1 = ["filePath", "${SERVER_LOG_ROOT}/access.log"]
    						accessLog2 = ["maximumSize", "10"]
    						accessLog3 = ["maximumBackupFiles", "20"]
    						accessLogAttributes = [accessLog1,accessLog2,accessLog3]
    						AdminConfig.modify(accessLog, accessLogAttributes)						
       		
    AdminConfig.save( )
    print " Finished Successfully"
#endDef



###########################################
#  	  Modify ErrorLog Settings        #
###########################################
def configErrorLog(serverName):
    print " Modifying Application Server "+serverName+" 's ErrorLog Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    errorlog = AdminConfig.showAttribute(server,"errorStreamRedirect")
  
    #print errorlog
    #print AdminConfig.showall(errorlog)

    errorAttribute1 = ["baseHour", ErrorLog_baseHour]
    errorAttribute2 = ["fileName", ErrorLog_fileName]
    errorAttribute3 = ["maxNumberOfBackupFiles", ErrorLog_maxNumberOfBackupFiles]
    errorAttribute4 = ["rolloverPeriod", ErrorLog_rolloverPeriod]
    errorAttribute5 = ["rolloverSize", ErrorLog_rolloverSize]
    errorAttribute6 = ["rolloverType", ErrorLog_rolloverType]
    
    errorAttributes = [errorAttribute1,errorAttribute2,errorAttribute3,errorAttribute4,errorAttribute5,errorAttribute6]

    AdminConfig.modify(errorlog, errorAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#  	   Modify SysLog Settings         #
###########################################
def configSysLog(serverName):
    print " Modifying Application Server "+serverName+" 's SysLog Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    errorlog = AdminConfig.showAttribute(server,"outputStreamRedirect")
  
    #print errorlog
    #print AdminConfig.showall(errorlog)

    errorAttribute1 = ["baseHour", SysLog_baseHour]
    errorAttribute2 = ["fileName", SysLog_fileName]
    errorAttribute3 = ["maxNumberOfBackupFiles", SysLog_maxNumberOfBackupFiles]
    errorAttribute4 = ["rolloverPeriod", SysLog_rolloverPeriod]
    errorAttribute5 = ["rolloverSize", SysLog_rolloverSize]
    errorAttribute6 = ["rolloverType", SysLog_rolloverType]
    
    errorAttributes = [errorAttribute1,errorAttribute2,errorAttribute3,errorAttribute4,errorAttribute5,errorAttribute6]

    AdminConfig.modify(errorlog, errorAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#         Modify Default Settings         #
###########################################
def configDefaultThreadPool(serverName):
    print " Modifying Application Server "+serverName+" 's Default.thread.pool Settings....."
    server = AdminConfig.getid("/Server:"+serverName )

    threadPool = AdminConfig.list("ThreadPool", server )
    threadPool = wsadminToList(threadPool);

    orb = ""
    for thread in threadPool:
       if (regexp("Default", thread) == 1):
		orb = thread				
       #endIf 
    #endFor 
    
    #print AdminConfig.showall(orb)
    
    orbAttribute3 = ["maximumSize", Default_maximumSize]
    orbAttribute4 = ["minimumSize", Default_minimumSize]
    
    orbAttributes = [orbAttribute3,orbAttribute4]
    AdminConfig.modify(orb, orbAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#       Modify WebContainer Settings      #
###########################################
def configWebContainerThreadPool(serverName):
    print " Modifying Application Server "+serverName+" 's WebContainer Settings....."
    server = AdminConfig.getid("/Server:"+serverName )

    threadPool = AdminConfig.list("ThreadPool", server )
    threadPool = wsadminToList(threadPool);

    webContainer = ""
    for thread in threadPool:
       if (regexp("WebContainer", thread) == 1):
		webContainer = thread				
       #endIf 
    #endFor 
    
    #print AdminConfig.showall(webContainer)
    
    webContainerbAttribute1 = ["inactivityTimeout", WebContainer_inactivityTimeout]
    webContainerbAttribute2 = ["isGrowable", WebContainer_isGrowable]
    webContainerbAttribute3 = ["maximumSize", WebContainer_maximumSize]
    webContainerbAttribute4 = ["minimumSize", WebContainer_minimumSize]
    
    webContainerAttributes = [webContainerbAttribute1,webContainerbAttribute2,webContainerbAttribute3,webContainerbAttribute4]
    AdminConfig.modify(webContainer, webContainerAttributes)
    
    #print AdminConfig.showAttribute(webContainer,"customProperties")
   
    varName = ["name", "ccc"]
    varValue = ["value", "ddd"]
    customPropAttrs = [varName, varValue]
    #AdminConfig.create("Property", webContainer, customPropAttrs)
    
    propertys=AdminConfig.list("Property",webContainer)
    propertys = wsadminToList(propertys);

    propertyOne = ""
    for thread in propertys:
       if (regexp("ccc", thread) == 1):
		propertyOne = thread				
       #endIf 
    #endFor 
    #AdminConfig.remove(propertyOne)

    AdminConfig.save( )
    print " Finished Successfully"
#endDef

###########################################
#     Modify ORB.thread.pool Settings     #
###########################################
def configORBThreadPool(serverName):
    print " Modifying Application Server "+serverName+" 's ORB.thread.pool Settings....."
    server = AdminConfig.getid("/Server:"+serverName )

    threadPool = AdminConfig.list("ThreadPool", server )
    threadPool = wsadminToList(threadPool);

    orb = ""
    for thread in threadPool:
       if (regexp("ORB.thread.pool", thread) == 1):
		orb = thread				
       #endIf 
    #endFor 
    
    #print AdminConfig.showall(orb)
    
    orbAttribute1 = ["inactivityTimeout", ORB_thread_pool_inactivityTimeout]
    orbAttribute2 = ["isGrowable", ORB_thread_pool_isGrowable]
    orbAttribute3 = ["maximumSize", ORB_thread_pool_maximumSize]
    orbAttribute4 = ["minimumSize", ORB_thread_pool_minimumSize]
    
    orbAttributes = [orbAttribute1,orbAttribute2,orbAttribute3,orbAttribute4]
    AdminConfig.modify(orb, orbAttributes)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef



###########################################
#  	Modify TraceService Settings      #
###########################################
def configTraceService(serverName):
    print " Modifying Application Server "+serverName+" 's TraceService Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    traceService = AdminConfig.list("TraceService", server )
    
    #print AdminConfig.showall(traceService)

    #print AdminConfig.showAttribute(traceService, "startupTraceSpecification" )

    traceAttribute1 = ["startupTraceSpecification", Trace_startupTraceSpecification]
    traceAttribute2 = ["enable", Trace_enable]
    traceAttributes = [traceAttribute1,traceAttribute2]
    AdminConfig.modify(traceService, traceAttributes)
    
    traceLog= AdminConfig.showAttribute(traceService, "traceLog" )
    #print traceLog
    traceLog1 = ["maxNumberOfBackupFiles", Trace_maxNumberOfBackupFiles]
    traceLog2 = ["fileName", Trace_fileName]
    traceLog3 = ["rolloverSize", Trace_rolloverSize]
    traceLogAttributes = [traceLog1,traceLog2,traceLog3]
    AdminConfig.modify(traceLog, traceLogAttributes)
    
    print AdminConfig.showall(traceService)
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

def configTraceServiceForConnLeak(serverName):
    print " Modifying Application Server "+serverName+" 's TraceService For ConnectionLeak Settings....."
    server = AdminConfig.getid("/Server:"+serverName )
    traceService = AdminConfig.list("TraceService", server )
    
    #print AdminConfig.showall(traceService)

    #print AdminConfig.showAttribute(traceService, "startupTraceSpecification" )
    traceStr = AdminConfig.showAttribute(traceService, "startupTraceSpecification" )
    #print traceStr.find("ConnLeakLogic=finest")
    if -1 == traceStr.find("ConnLeakLogic=finest"):
    	traceStr = traceStr + ":ConnLeakLogic=finest"
    traceAttribute1 = ["startupTraceSpecification", traceStr]
    traceAttribute2 = ["enable", Trace_enable]
    traceAttributes = [traceAttribute1,traceAttribute2]
    AdminConfig.modify(traceService, traceAttributes)
    
    traceLog= AdminConfig.showAttribute(traceService, "traceLog" )
    #print traceLog
    traceLog1 = ["maxNumberOfBackupFiles", Trace_maxNumberOfBackupFiles]
    traceLog2 = ["fileName", Trace_fileName]
    traceLog3 = ["rolloverSize", Trace_rolloverSize]
    traceLogAttributes = [traceLog1,traceLog2,traceLog3]
    AdminConfig.modify(traceLog, traceLogAttributes)
    
    print AdminConfig.showall(traceService)
    
    AdminConfig.save( )
    print " Finished Successfully"
#endDef

############################################
#      Modify each appserver's config      #
############################################
nodename = "test"
if isND():
	nodename = getDmgrNodeName()
else:
	node_ids = _splitlines(AdminConfig.list( 'Node' ))
	for node_id in node_ids:
		nodename = getNodeName(node_id)
print nodename

appServers = listServersOfTypeSecp('APPLICATION_SERVER')
print appServers

for appServer in appServers:

	configErrorLog(appServer)
	configSysLog(appServer)
	configTraceServiceForConnLeak(appServer)
	configGCEntries(appServer)
#	if versionAtLeast(nodename, "7.0.0.31"):
#		configXdumpBigObjEntries(appServer)
	configXdumCoreFileEntries(appServer)
#	configHangCustomProperties(appServer)
	configWCInboundDefaultAccessLog(appServer)
	
#endFor 